home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termMain.c < prev    next >
C/C++ Source or Header  |  1995-07-08  |  106KB  |  5,638 lines

  1. /*
  2. **    termMain.c
  3. **
  4. **    Program main routines and event loop
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Argument vectors offsets. */
  13.  
  14. enum    {    ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
  15.         ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,ARG_LANGUAGE,
  16.  
  17.         ARG_COUNT
  18.     };
  19.  
  20.     /* Argument template. */
  21.  
  22. #define ARGTEMPLATE    "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,QUIET/S,BEHIND/S,DEBUG/S,LANGUAGE/K"
  23.  
  24.     /* Local config path variable. */
  25.  
  26. STATIC STRPTR        ConfigPath;
  27. STATIC UBYTE __far    ThePath[MAX_FILENAME_LENGTH];
  28.  
  29.     /* Local dialing list. */
  30.  
  31. STATIC struct List    *LocalDialList;
  32. STATIC LONG         LocalCount = -1;
  33.  
  34.     /* Startup file name. */
  35.  
  36. STATIC UBYTE __far    StartupFile[MAX_FILENAME_LENGTH];
  37.  
  38.     /* Did we hang up the line? */
  39.  
  40. STATIC BOOLEAN        HungUp = FALSE;
  41.  
  42.     /* Poll OwnDevUnit.library for the device to become available again? */
  43.  
  44. STATIC BOOLEAN        PollODU = FALSE;
  45. STATIC UWORD        PollODUCount = 0;
  46.  
  47.     /* Cloned CLI data. */
  48.  
  49. STATIC struct CommandLineInterface    *LocalCLI;
  50. STATIC BPTR                 OldCLI;
  51.  
  52.     /* Segment split routine, has to be local. */
  53.  
  54. STATIC struct Process * __regargs    SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
  55. STATIC VOID                CloseLibs(VOID);
  56.  
  57.     /* main():
  58.      *
  59.      *    This is our main entry point, check for the right
  60.      *    Kickstart version and fire off the background task
  61.      *    if approritate.
  62.      */
  63.  
  64. LONG
  65. main()
  66. {
  67.     STRPTR Result;
  68.  
  69.         /* Are we running as a child of Workbench? */
  70.  
  71.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  72.  
  73.     if(!ThisProcess -> pr_CLI)
  74.     {
  75.         WaitPort(&ThisProcess -> pr_MsgPort);
  76.  
  77.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  78.     }
  79.     else
  80.         WBenchMsg = NULL;
  81.  
  82.         /* Now try to open dos.library and utility.library and go on examining
  83.          * our calling parameters.
  84.          */
  85.  
  86.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  87.     {
  88.         CloseLibs();
  89.  
  90.         return(RETURN_FAIL);
  91.     }
  92.  
  93.     if(!(UtilityBase = OpenLibrary("utility.library",0)))
  94.     {
  95.         CloseLibs();
  96.  
  97.         return(RETURN_FAIL);
  98.     }
  99.  
  100.         /* We were called from Shell. */
  101.  
  102.     if(ThisProcess -> pr_CLI)
  103.     {
  104.         STRPTR *ArgArray;
  105.  
  106.             /* Use the cute ReadArgs parser, allocate the
  107.              * argument vectors...
  108.              */
  109.  
  110.         if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  111.         {
  112.             struct RDArgs *ArgsPtr;
  113.  
  114.             if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  115.             {
  116.                 ArgsPtr -> RDA_ExtHelp =    "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
  117.                                 "            [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
  118.                                 "            [NEW] [SYNC] [QUIET] [BEHIND] [LANGUAGE <Name>]\n\n"
  119.                                 "     Window = Output window specifier\n"
  120.                                 "  PubScreen = Name of public screen to open window upon\n"
  121.                                 "    Startup = ARexx script file to run on startup\n"
  122.                                 "   Settings = Main configuration file name or path name to search for it\n"
  123.                                 "       Unit = Serial device driver unit number\n"
  124.                                 "     Device = Serial device driver name\n"
  125.                                 "        New = Spawn a new `term' process\n"
  126.                                 "       Sync = Keep links to Shell environment\n"
  127.                                 "      Quiet = Start iconified\n"
  128.                                 "     Behind = Open screen behind all other screens, don't activate the window\n\n"
  129.                                 "   Language = Language to use for the user interface\n\n";
  130.  
  131.                     /* Parse the args (if any). */
  132.  
  133.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  134.                 {
  135.                         /* Pop a running `term' to the front? */
  136.  
  137.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_NEW])
  138.                     {
  139.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  140.                         {
  141.                             if(TermPort -> TopWindow)
  142.                                 BumpWindow(TermPort -> TopWindow);
  143.                         }
  144.  
  145.                         TermPort = NULL;
  146.  
  147.                         FreeArgs(ArgsPtr);
  148.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  149.                         FreeVec(ArgArray);
  150.  
  151.                         CloseLibs();
  152.  
  153.                         return(RETURN_OK);
  154.                     }
  155.  
  156.                     if(ArgArray[ARG_DEBUG])
  157.                         DebugFlag = TRUE;
  158.  
  159.                         /* Special language requested? */
  160.  
  161.                     if(ArgArray[ARG_LANGUAGE])
  162.                         strcpy(Language,ArgArray[ARG_LANGUAGE]);
  163.  
  164.                         /* Are we to use a special settings path? */
  165.  
  166.                     if(ArgArray[ARG_SETTINGS])
  167.                     {
  168.                         ConfigPath = ThePath;
  169.  
  170.                         strcpy(ThePath,ArgArray[ARG_SETTINGS]);
  171.                     }
  172.  
  173.                         /* Are we to use a special ARexx host port name? */
  174.  
  175.                     if(ArgArray[ARG_PORTNAME])
  176.                         strcpy(RexxPortName,ArgArray[ARG_PORTNAME]);
  177.  
  178.                         /* Are we to use a special output window name? */
  179.  
  180.                     if(ArgArray[ARG_WINDOW])
  181.                         strcpy(WindowName,ArgArray[ARG_WINDOW]);
  182.  
  183.                         /* Are we to run an ARexx script on startup? */
  184.  
  185.                     if(ArgArray[ARG_STARTUP])
  186.                         strcpy(StartupFile,ArgArray[ARG_STARTUP]);
  187.  
  188.                         /* Are we to open a window on a public screen? */
  189.  
  190.                     if(ArgArray[ARG_PUBSCREEN])
  191.                         strcpy(SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
  192.  
  193.                         /* Are we to use a special device? */
  194.  
  195.                     if(ArgArray[ARG_DEVICE])
  196.                     {
  197.                         strcpy(NewDevice,ArgArray[ARG_DEVICE]);
  198.  
  199.                         UseNewDevice = TRUE;
  200.                     }
  201.  
  202.                         /* Are we to use a special unit number? */
  203.  
  204.                     if(ArgArray[ARG_UNIT])
  205.                     {
  206.                         NewUnit = *(LONG *)ArgArray[ARG_UNIT];
  207.  
  208.                         UseNewUnit = TRUE;
  209.                     }
  210.  
  211.                         /* Are we to start up iconified? */
  212.  
  213.                     if(ArgArray[ARG_QUIET])
  214.                     {
  215.                         if(!StartupFile[0])
  216.                             DoIconify = TRUE;
  217.                     }
  218.  
  219.                         /* Hide the screen and don't activate the window? */
  220.  
  221.                     if(ArgArray[ARG_BEHIND])
  222.                         KeepQuiet = TRUE;
  223.  
  224.                         /* We are to keep our links to
  225.                          * the Shell.
  226.                          */
  227.  
  228.                     if(ArgArray[ARG_SYNC] || !ThisProcess -> pr_HomeDir)
  229.                     {
  230.                         BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
  231.  
  232.                             /* Open our resources and
  233.                              * squeak on failure.
  234.                              */
  235.  
  236.                         if(Result = OpenAll(ConfigPath))
  237.                         {
  238.                             if(Result[0])
  239.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  240.  
  241.                             FreeArgs(ArgsPtr);
  242.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  243.                             FreeVec(ArgArray);
  244.  
  245.                             CloseAll(TRUE);
  246.  
  247.                             return(RETURN_FAIL);
  248.                         }
  249.  
  250.                             /* Go into main input
  251.                              * loop.
  252.                              */
  253.  
  254.                         if(StackSize(NULL) < 16384)
  255.                         {
  256.                             LONG Success;
  257.  
  258.                             StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
  259.                         }
  260.                         else
  261.                             HandleInput();
  262.  
  263.                             /* Free the argument
  264.                              * data.
  265.                              */
  266.  
  267.                         FreeArgs(ArgsPtr);
  268.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  269.                         FreeVec(ArgArray);
  270.  
  271.                             /* Restore old priority. */
  272.  
  273.                         SetTaskPri(ThisProcess,(LONG)OldPri);
  274.  
  275.                             /* Terminate execution. */
  276.  
  277.                         CloseAll(TRUE);
  278.  
  279.                         return(RETURN_OK);
  280.                     }
  281.  
  282.                     FreeArgs(ArgsPtr);
  283.                 }
  284.                 else
  285.                 {
  286.                     PrintFault(IoErr(),"term");
  287.  
  288.                     FreeDosObject(DOS_RDARGS,ArgsPtr);
  289.                     FreeVec(ArgArray);
  290.  
  291.                     CloseLibs();
  292.  
  293.                     return(RETURN_ERROR);
  294.                 }
  295.  
  296.                 FreeDosObject(DOS_RDARGS,ArgsPtr);
  297.             }
  298.  
  299.             FreeVec(ArgArray);
  300.  
  301.                 /* Create a new process from our code. */
  302.  
  303.             if(!SegmentSplit("term main process",0,16384,HandleInput))
  304.             {
  305.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  306.  
  307.                 CloseLibs();
  308.  
  309.                 return(RETURN_FAIL);
  310.             }
  311.         }
  312.         else
  313.         {
  314.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  315.  
  316.             CloseLibs();
  317.  
  318.             return(RETURN_FAIL);
  319.         }
  320.     }
  321.     else
  322.     {
  323.             /* Try to create a local CLI structure so
  324.              * Shell commands will receive a valid
  325.              * search path list.
  326.              */
  327.  
  328.         if(LocalCLI = CloneCLI(&WBenchMsg -> sm_Message))
  329.         {
  330.             OldCLI = ThisProcess -> pr_CLI;
  331.  
  332.             ThisProcess -> pr_CLI = MKBADDR(LocalCLI);
  333.         }
  334.  
  335.         WBenchLock = CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
  336.  
  337.             /* Open icon.library, we want to take a
  338.              * look at the icon.
  339.              */
  340.  
  341.         if(IconBase = OpenLibrary("icon.library",0))
  342.         {
  343.             struct DiskObject *Icon;
  344.  
  345.                 /* Try to read the icon file. */
  346.  
  347.             if(Icon = GetProgramIcon())
  348.             {
  349.                 STRPTR Type;
  350.  
  351.                 if(FindToolType(Icon -> do_ToolTypes,"DEBUG"))
  352.                     DebugFlag = TRUE;
  353.  
  354.                     /* Look for a `Language' tooltype. */
  355.  
  356.                 if(Type = FindToolType(Icon -> do_ToolTypes,"LANGUAGE"))
  357.                     strcpy(Language,Type);
  358.  
  359.                     /* Look for a `Settings' tooltype. */
  360.  
  361.                 if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
  362.                 {
  363.                         /* Remember the path and continue. */
  364.  
  365.                     strcpy(ThePath,ConfigPath);
  366.  
  367.                     ConfigPath = ThePath;
  368.                 }
  369.  
  370.                     /* Look for a `Portname' tooltype. */
  371.  
  372.                 if(Type = FindToolType(Icon -> do_ToolTypes,"PORTNAME"))
  373.                     strcpy(RexxPortName,Type);
  374.                 else
  375.                     RexxPortName[0] = 0;
  376.  
  377.                     /* Look for a `Window' tooltype. */
  378.  
  379.                 if(Type = FindToolType(Icon -> do_ToolTypes,"WINDOW"))
  380.                     strcpy(WindowName,Type);
  381.                 else
  382.                     WindowName[0] = 0;
  383.  
  384.                     /* Look for a `Pubscreen' tooltype. */
  385.  
  386.                 if(Type = FindToolType(Icon -> do_ToolTypes,"PUBSCREEN"))
  387.                     strcpy(SomePubScreenName,Type);
  388.                 else
  389.                     SomePubScreenName[0] = 0;
  390.  
  391.                     /* Look for a `Startup' tooltype. */
  392.  
  393.                 if(Type = FindToolType(Icon -> do_ToolTypes,"STARTUP"))
  394.                     strcpy(StartupFile,Type);
  395.                 else
  396.                     StartupFile[0] = 0;
  397.  
  398.                     /* Look for a `Device' tooltype. */
  399.  
  400.                 if(Type = FindToolType(Icon -> do_ToolTypes,"DEVICE"))
  401.                 {
  402.                     if(Type[0])
  403.                     {
  404.                         strcpy(NewDevice,Type);
  405.  
  406.                         UseNewDevice = TRUE;
  407.                     }
  408.                 }
  409.  
  410.                     /* Look for a `Unit' tooltype. */
  411.  
  412.                 if(Type = FindToolType(Icon -> do_ToolTypes,"UNIT"))
  413.                 {
  414.                     if(Type[0])
  415.                     {
  416.                         NewUnit = Atol(Type);
  417.  
  418.                         UseNewUnit = TRUE;
  419.                     }
  420.                 }
  421.  
  422.                     /* Look for a `Quiet' tooltype. */
  423.  
  424.                 if(FindToolType(Icon -> do_ToolTypes,"QUIET"))
  425.                 {
  426.                     if(!StartupFile[0])
  427.                         DoIconify = TRUE;
  428.                 }
  429.  
  430.                     /* Look for a `Behind' tooltype. */
  431.  
  432.                 if(FindToolType(Icon -> do_ToolTypes,"BEHIND"))
  433.                     KeepQuiet = TRUE;
  434.  
  435.                     /* Free the icon. */
  436.  
  437.                 FreeDiskObject(Icon);
  438.             }
  439.  
  440.             CloseLibrary(IconBase);
  441.  
  442.             IconBase = NULL;
  443.         }
  444.  
  445.             /* Initialize this, so OpenAll will work with
  446.              * correct data.
  447.              */
  448.  
  449.         TermPort = (struct TermPort *)FindPort("term Port");
  450.  
  451.             /* We were called from Workbench. */
  452.  
  453.         if(Result = OpenAll(ConfigPath))
  454.         {
  455.             if(IntuitionBase && Result[0])
  456.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  457.  
  458.             CloseAll(TRUE);
  459.         }
  460.         else
  461.         {
  462.             if(StackSize(NULL) < 16384)
  463.             {
  464.                 LONG Success;
  465.  
  466.                 StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
  467.             }
  468.             else
  469.                 HandleInput();
  470.         }
  471.     }
  472.  
  473.     return(RETURN_OK);
  474. }
  475.  
  476.     /* CloseLibs():
  477.      *
  478.      *    Plain and simple: close two libraries and clean up.
  479.      */
  480.  
  481. STATIC VOID
  482. CloseLibs(VOID)
  483. {
  484.     if(UtilityBase)
  485.     {
  486.         CloseLibrary(UtilityBase);
  487.  
  488.         UtilityBase = NULL;
  489.     }
  490.  
  491.     if(WBenchMsg)
  492.         CurrentDir(WBenchLock);
  493.  
  494.     if(DOSBase)
  495.     {
  496.         CloseLibrary(DOSBase);
  497.  
  498.         DOSBase = NULL;
  499.     }
  500.  
  501.     if(WBenchMsg)
  502.     {
  503.         Forbid();
  504.  
  505.         ReplyMsg((struct Message *)WBenchMsg);
  506.     }
  507. }
  508.  
  509.     /* ProcessCleanup(register __d1 BPTR SegList):
  510.      *
  511.      *    Frees all resource the main process has allocated when
  512.      *    it exits.
  513.      */
  514.  
  515. STATIC VOID __saveds __asm
  516. ProcessCleanup(register __d1 BPTR SegList)
  517. {
  518.     CloseAll(FALSE);
  519.  
  520.     Forbid();
  521.  
  522.     UnLoadSeg(SegList);
  523.  
  524.     CloseLibrary(DOSBase);
  525.  
  526.     DOSBase = NULL;
  527. }
  528.  
  529.     /* SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function):
  530.      *
  531.      *    Create a new process from the current one.
  532.      */
  533.  
  534. STATIC struct Process * __regargs
  535. SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
  536. {
  537.     struct Process            *Child;
  538.     struct CommandLineInterface    *CLI;
  539.  
  540.     CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
  541.  
  542.     Forbid();
  543.  
  544.     Child = CreateNewProcTags(
  545.         NP_CommandName,    "term",
  546.         NP_Name,    Name,
  547.         NP_Priority,    Pri,
  548.         NP_StackSize,    StackSize,
  549.         NP_Entry,    Function,
  550.         NP_Cli,        TRUE,
  551.         NP_ExitCode,    ProcessCleanup,
  552.         NP_ExitData,    CLI -> cli_Module,
  553.     TAG_DONE);
  554.  
  555.     if(Child)
  556.         CLI -> cli_Module = NULL;
  557.  
  558.     Permit();
  559.  
  560.     return(Child);
  561. }
  562.  
  563.     /* HandleInput():
  564.      *
  565.      *    This is our main input loop (check window & serial).
  566.      */
  567.  
  568. VOID __saveds
  569. HandleInput()
  570. {
  571.     STRPTR    Error;
  572.     BOOLEAN    AlmostFinished = FALSE;
  573.     BYTE    (* LocalSendLine)(register STRPTR,register LONG);
  574.  
  575.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  576.  
  577.         /* Open the resources we need. */
  578.  
  579.     if(!IntuitionBase)
  580.     {
  581.         STRPTR Result;
  582.  
  583.         if(Result = OpenAll(ConfigPath))
  584.         {
  585.             if(IntuitionBase && Result[0])
  586.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  587.  
  588.             if(WBenchMsg)
  589.                 CloseAll(TRUE);
  590.  
  591.             return;
  592.         }
  593.     }
  594.  
  595.         /* Tell the user what he probably doesn't know yet. */
  596.  
  597.     if(TermVersion > Config -> SerialConfig -> LastVersionSaved || (TermVersion == Config -> SerialConfig -> LastVersionSaved && TermRevision > Config -> SerialConfig -> LastRevisionSaved))
  598.     {
  599.         BlockWindows();
  600.  
  601.         ScreenToFront(Window -> WScreen);
  602.  
  603.         DisplayBeep(Window -> WScreen);
  604.         DisplayBeep(Window -> WScreen);
  605.  
  606.         ShowInfo(Window,LocaleString(MSG_ATTENTION_PLEASE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_REMINDER_TXT));
  607.  
  608.         ReleaseWindows();
  609.     }
  610.  
  611.         /* Give a hint. */
  612.  
  613.     if(Config -> MiscConfig -> ProtectiveMode && !FirstInvocation)
  614.     {
  615.         BlockWindows();
  616.  
  617.         if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE && !Config -> SerialConfig -> DirectConnection)
  618.         {
  619.             ScreenToFront(Window -> WScreen);
  620.  
  621.             if(MyEasyRequest(Window,LocaleString(MSG_NO_RTSCTS_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Config -> SerialConfig -> BaudRate))
  622.             {
  623.                 SaveConfig(Config,PrivateConfig);
  624.  
  625.                 Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
  626.  
  627.                 ConfigSetup();
  628.             }
  629.         }
  630.  
  631.         if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> ModemConfig -> ConnectAutoBaud)
  632.         {
  633.             ScreenToFront(Window -> WScreen);
  634.  
  635.             if(MyEasyRequest(Window,LocaleString(MSG_AUTOBAUD_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  636.             {
  637.                 SaveConfig(Config,PrivateConfig);
  638.  
  639.                 Config -> ModemConfig -> ConnectAutoBaud = FALSE;
  640.  
  641.                 ConfigSetup();
  642.             }
  643.         }
  644.  
  645.         ReleaseWindows();
  646.     }
  647.  
  648.         // Don't confuse the user yet, do it later ;-)
  649.  
  650.     FirstInvocation = FALSE;
  651.  
  652.         /* Start the online timer if a carrier is present? */
  653.  
  654.     if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
  655.     {
  656.             /* Is the carrier signal present? */
  657.  
  658.         if(!(GetSerialStatus() & CIAF_COMCD))
  659.         {
  660.                 /* Go into online state. */
  661.  
  662.             ObtainSemaphore(&OnlineSemaphore);
  663.  
  664.             WasOnline        = FALSE;
  665.             Online            = TRUE;
  666.  
  667.             ReleaseSemaphore(&OnlineSemaphore);
  668.  
  669.             BaudCount        = 0;
  670.             BaudBuffer[0]        = 0;
  671.             BaudPending        = FALSE;
  672.  
  673.             CurrentPay        = 0;
  674.  
  675.             ObtainSemaphore(&PatternSemaphore);
  676.  
  677.             ChosenEntry        = NULL;
  678.             ChosenPattern        = NULL;
  679.  
  680.             ReleaseSemaphore(&PatternSemaphore);
  681.  
  682.             Password[0]        = 0;
  683.             UserName[0]        = 0;
  684.  
  685.             SendStartup        = FALSE;
  686.  
  687.             LimitCount        = -1;
  688.  
  689.             CurrentBBSName[0]    = 0;
  690.             CurrentBBSComment[0]    = 0;
  691.             CurrentBBSNumber[0]    = 0;
  692.  
  693.             SetDialMenu(FALSE);
  694.         }
  695.     }
  696.  
  697.         /* Start up iconified? */
  698.  
  699.     if(DoIconify)
  700.     {
  701.         HandleIconify();
  702.  
  703.         DoIconify = FALSE;
  704.  
  705.         if(MainTerminated)
  706.             goto Stop;
  707.     }
  708.  
  709.     if(!KeepQuiet)
  710.         BumpWindow(Window);
  711.  
  712.         /* Set up the public screen data. */
  713.  
  714.     PubScreenStuff();
  715.  
  716.         /* Change program priority. */
  717.  
  718.     SetTaskPri(ThisProcess,(LONG)Config -> MiscConfig -> Priority);
  719.  
  720.     BlockWindows();
  721.  
  722.         /* Load the phone book. */
  723.  
  724.     LoadPhonebook(LastPhone);
  725.  
  726.         /* Build new menu strip. */
  727.  
  728.     if(Error = BuildMenu())
  729.     {
  730.         if(IntuitionBase)
  731.             MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  732.  
  733.         CloseAll(TRUE);
  734.  
  735.         return;
  736.     }
  737.     else
  738.     {
  739.         if(Online)
  740.             SetDialMenu(FALSE);
  741.     }
  742.  
  743.         /* Show our business card. */
  744.  
  745.     if(!StartupFile[0] && !Config -> CommandConfig -> StartupMacro[0] && !KeepQuiet)
  746.     {
  747.         if(ShowAbout(TRUE))
  748.             while(HandleRexx());
  749.     }
  750.  
  751.     ReleaseWindows();
  752.  
  753.         /* Don't do anything silly. */
  754.  
  755.     KeepQuiet = FALSE;
  756.  
  757.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  758.  
  759.         /* Initialize the modem. */
  760.  
  761.     LocalSendLine    = SendLine;
  762.     SendLine    = SendLineDial;
  763.  
  764.     SerialCommand(Config -> ModemConfig -> ModemInit);
  765.  
  766.         /* Execute the startup macro (if any). */
  767.  
  768.     if(Config -> CommandConfig -> StartupMacro[0])
  769.         SerialCommand(Config -> CommandConfig -> StartupMacro);
  770.  
  771.     if(SendLine == SendLineDial)
  772.         SendLine = LocalSendLine;
  773.  
  774.     /*
  775.     {
  776.         STRPTR Warning =
  777.             "\f  Just to make sure you know what you are using:\r\n"
  778.             "\r\n"
  779.             "     \033#6This really is a\r\n"
  780.             "        \033[5m\033#3BETA TEST\r\n"
  781.             "        \033#4BETA TEST\033[0m\r\n"
  782.             "         \033#6release!\r\n"
  783.             "\033#5\r\n"
  784.             "                   \033[4mDISCLAIMER:\033[0m\r\n"
  785.             "\r\n"
  786.             "This  product  is  meant  for educational purposes\r\n"
  787.             "only.   If   condition   persists,   consult  your\r\n"
  788.             "physician.  Edited  for  television. See label for\r\n"
  789.             "sequence.  Avoid  contact  with  skin. No purchase\r\n"
  790.             "necessary.  Use  only in well-ventilated area. Not\r\n"
  791.             "recommended  for  children.  No  anchovies  unless\r\n"
  792.             "otherwise  specified.  Driver does not carry cash.\r\n"
  793.             "This supersedes all previous notices.\r\n";
  794.  
  795.         ConProcess(Warning,strlen(Warning));
  796.     }
  797.     */
  798.  
  799.         /* Go into input loop... */
  800.  
  801. Loop:    while(!MainTerminated)
  802.     {
  803.         if(Recording)
  804.         {
  805.             if(RecordingLine)
  806.                 Status = STATUS_RECORDING_LINE;
  807.             else
  808.                 Status = STATUS_RECORDING;
  809.         }
  810.  
  811.             /* Handle the signal responses. */
  812.  
  813.         HandleResponse();
  814.  
  815.         if(RebuildMenu)
  816.         {
  817.             if(Error = BuildMenu())
  818.             {
  819.                 if(IntuitionBase)
  820.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  821.  
  822.                 MainTerminated = TRUE;
  823.  
  824.                 break;
  825.             }
  826.  
  827.             RebuildMenu = FALSE;
  828.         }
  829.  
  830.             /* Are we to run an ARexx script file? */
  831.  
  832.         if(StartupFile[0])
  833.         {
  834.             BlockWindows();
  835.  
  836.             SendARexxCommand(StartupFile,TRUE);
  837.  
  838.             ReleaseWindows();
  839.  
  840.             StartupFile[0] = 0;
  841.         }
  842.  
  843.             /* Are we to leave the main loop? */
  844.  
  845.         if(MainTerminated)
  846.             break;
  847.  
  848.             /* Make the user notice not too obvious events. */
  849.  
  850.         if(FlowInfo . Changed)
  851.             HandleFlowChange();
  852.  
  853.             /* Are we no longer online? */
  854.  
  855.         ObtainSemaphore(&OnlineSemaphore);
  856.  
  857.         if(!Online)
  858.         {
  859.             if(WasOnline)
  860.             {
  861.                 ReleaseSemaphore(&OnlineSemaphore);
  862.  
  863.                 HandleOnlineCleanup(HungUp);
  864.  
  865.                 ObtainSemaphore(&OnlineSemaphore);
  866.  
  867.                 WasOnline = FALSE;
  868.  
  869.                 ReleaseSemaphore(&OnlineSemaphore);
  870.  
  871.                 HungUp = FALSE;
  872.             }
  873.             else
  874.                 ReleaseSemaphore(&OnlineSemaphore);
  875.         }
  876.         else
  877.             ReleaseSemaphore(&OnlineSemaphore);
  878.  
  879.             /* Now for public screen mode changes. */
  880.  
  881.         if(FixPubScreenMode)
  882.             PubScreenStuff();
  883.  
  884.             /* Now for window size changes. */
  885.  
  886.         if(FixScreenSize)
  887.             ScreenSizeStuff();
  888.  
  889.             /* Somebody told us to re-open the display
  890.              * (changed the terminal emulation/colour
  891.              * mode, etc.).
  892.              */
  893.  
  894.         if(ResetDisplay)
  895.         {
  896.             if(!DisplayReset())
  897.                 break;
  898.         }
  899.  
  900.             /* Let's see if we still have to display the
  901.              * online cost.
  902.              */
  903.  
  904.         ObtainSemaphore(&OnlineSemaphore);
  905.  
  906.         if(CurrentPay && !Online)
  907.         {
  908.             ReleaseSemaphore(&OnlineSemaphore);
  909.  
  910.                 /* Reset the text rendering styles, font, etc. in
  911.                  * order to keep the following text from getting
  912.                  * illegible.
  913.                  */
  914.  
  915.             SoftReset();
  916.  
  917.                 /* Display how much we expect
  918.                  * the user will have to pay for
  919.                  * this call.
  920.                  */
  921.  
  922.             ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  923.  
  924.             CurrentPay = 0;
  925.         }
  926.         else
  927.             ReleaseSemaphore(&OnlineSemaphore);
  928.  
  929.             /* Iconify the program? */
  930.  
  931.         if(DoIconify)
  932.         {
  933.             HandleIconify();
  934.  
  935.             if(MainTerminated)
  936.                 break;
  937.         }
  938.  
  939.             /* Reset the serial driver? */
  940.  
  941.         if(ResetSerial)
  942.         {
  943.             HandleSerialReset();
  944.  
  945.             if(MainTerminated)
  946.                 break;
  947.         }
  948.  
  949.             /* We are to release the serial.device (or
  950.              * whatever we are using) for some reason.
  951.              */
  952.  
  953.         if(ReleaseSerial)
  954.         {
  955.             HandleSerialRelease();
  956.  
  957.             if(MainTerminated)
  958.                 break;
  959.         }
  960.  
  961.             /* Invoke the dialing function? */
  962.  
  963.         if(DoDial != DIAL_IGNORE)
  964.         {
  965.             ObtainSemaphore(&OnlineSemaphore);
  966.  
  967.             if(Online)
  968.             {
  969.                 ReleaseSemaphore(&OnlineSemaphore);
  970.  
  971.                 FreeDialList(FALSE);
  972.  
  973.                 DoDial = DIAL_IGNORE;
  974.  
  975.                 Forbid();
  976.  
  977.                 if(DialMsg)
  978.                 {
  979.                     DialMsg -> rm_Result1 = RC_WARN;
  980.                     DialMsg -> rm_Result2 = 0;
  981.  
  982.                     ReplyMsg(DialMsg);
  983.  
  984.                     DialMsg = NULL;
  985.                 }
  986.  
  987.                 Permit();
  988.             }
  989.             else
  990.             {
  991.                 ReleaseSemaphore(&OnlineSemaphore);
  992.  
  993.                 if(DoDial == DIAL_LIST)
  994.                 {
  995.                     BYTE OldStatus = Status;
  996.  
  997.                     DoDial = DIAL_IGNORE;
  998.  
  999.                     BlockWindows();
  1000.  
  1001.                     DialPanel();
  1002.  
  1003.                     FreeDialList(FALSE);
  1004.  
  1005.                     Status = OldStatus;
  1006.  
  1007.                     SetRedialMenu();
  1008.  
  1009.                     ReleaseWindows();
  1010.                 }
  1011.                 else
  1012.                 {
  1013.                     DoDial = DIAL_IGNORE;
  1014.  
  1015.                     HandleMenuCode(MEN_REDIAL,NULL);
  1016.                 }
  1017.             }
  1018.         }
  1019.  
  1020.             /* Can we quit now? */
  1021.  
  1022.         if(AlmostFinished && !CantQuit)
  1023.             break;
  1024.     }
  1025.  
  1026.         /* Don't exit until all background processes
  1027.          * have terminated.
  1028.          */
  1029.  
  1030.     if(MainTerminated && CantQuit)
  1031.     {
  1032.         MainTerminated = FALSE;
  1033.         AlmostFinished = TRUE;
  1034.  
  1035.         goto Loop;
  1036.     }
  1037.  
  1038.         /* User wants to quit term, so let's try to close
  1039.          * our magnificient screen and exit.
  1040.          */
  1041.  
  1042. Stop:    if(Screen || SharedScreen)
  1043.     {
  1044.         struct Screen *WhichScreen;
  1045.  
  1046.             /* There can be only one... */
  1047.  
  1048.         if(Screen)
  1049.             WhichScreen = Screen;
  1050.         else
  1051.             WhichScreen = SharedScreen;
  1052.  
  1053.             // Can we quit now?
  1054.  
  1055.         if(!(PubScreenStatus(WhichScreen,PSNF_PRIVATE) & PSNF_PRIVATE))
  1056.         {
  1057.             BlockWindows();
  1058.  
  1059.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  1060.  
  1061.             ReleaseWindows();
  1062.  
  1063.             AlmostFinished = MainTerminated = FALSE;
  1064.  
  1065.             goto Loop;
  1066.         }
  1067.     }
  1068.  
  1069.         /* Send the modem exit command, shut down the
  1070.          * serial.device and close all resources.
  1071.          */
  1072.  
  1073.     LocalSendLine    = SendLine;
  1074.     SendLine    = SendLineDial;
  1075.  
  1076.     SerialCommand(Config -> ModemConfig -> ModemExit);
  1077.  
  1078.     if(SendLine == SendLineDial)
  1079.         SendLine = LocalSendLine;
  1080.  
  1081.     ClearSerial();
  1082.  
  1083.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  1084.  
  1085.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  1086.  
  1087.     if(Phonebook && PhoneSize)
  1088.         DeletePhonebook(Phonebook,PhoneSize,TRUE);
  1089.  
  1090.         /* Clean up. */
  1091.  
  1092.     if(LocalCLI)
  1093.     {
  1094.         ThisProcess -> pr_CLI = OldCLI;
  1095.  
  1096.         DeleteCLI(LocalCLI);
  1097.     }
  1098.  
  1099.     if(!ThisProcess -> pr_CLI)
  1100.         CloseAll(TRUE);
  1101. }
  1102.  
  1103.     /* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF):
  1104.      *
  1105.      *    Transmit text the user typed or pasted via the
  1106.      *    clipboard.
  1107.      */
  1108.  
  1109. STATIC VOID __regargs
  1110. SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF)
  1111. {
  1112.     UBYTE Mask,c;
  1113.  
  1114.     if(Config -> SerialConfig -> StripBit8)
  1115.         Mask = 0x7F;
  1116.     else
  1117.         Mask = 0xFF;
  1118.  
  1119.     while(Len--)
  1120.     {
  1121.         switch(CharType[c = (*Buffer++) & Mask])
  1122.         {
  1123.             case CHAR_ENTER:
  1124.  
  1125.                 if(Status == STATUS_HOLDING)
  1126.                 {
  1127.                     if(Bell)
  1128.                         BellSignal();
  1129.                 }
  1130.                 else
  1131.                 {
  1132.                     if(ConvertLF)
  1133.                     {
  1134.                         switch(Config -> TerminalConfig -> SendCR)
  1135.                         {
  1136.                             case EOL_LF:
  1137.  
  1138.                                 SerWrite("\n",1);
  1139.                                 break;
  1140.  
  1141.                             case EOL_CR:
  1142.  
  1143.                                 SerWrite("\r",1);
  1144.                                 break;
  1145.  
  1146.                             case EOL_LFCR:
  1147.  
  1148.                                 SerWrite("\n\r",2);
  1149.                                 break;
  1150.  
  1151.                             case EOL_CRLF:
  1152.  
  1153.                                 SerWrite("\r\n",2);
  1154.                                 break;
  1155.                         }
  1156.                     }
  1157.                     else
  1158.                     {
  1159.                         switch(Config -> TerminalConfig -> SendLF)
  1160.                         {
  1161.                             case EOL_LF:
  1162.  
  1163.                                 SerWrite("\n",1);
  1164.                                 break;
  1165.  
  1166.                             case EOL_CR:
  1167.  
  1168.                                 SerWrite("\r",1);
  1169.                                 break;
  1170.  
  1171.                             case EOL_LFCR:
  1172.  
  1173.                                 SerWrite("\n\r",2);
  1174.                                 break;
  1175.  
  1176.                             case EOL_CRLF:
  1177.  
  1178.                                 SerWrite("\r\n",2);
  1179.                                 break;
  1180.                         }
  1181.                     }
  1182.                 }
  1183.  
  1184.                 break;
  1185.  
  1186.             case CHAR_RETURN:
  1187.  
  1188.                 if(Status == STATUS_HOLDING)
  1189.                 {
  1190.                     if(Bell)
  1191.                         BellSignal();
  1192.                 }
  1193.                 else
  1194.                 {
  1195.                     switch(Config -> TerminalConfig -> SendCR)
  1196.                     {
  1197.                         case EOL_LF:
  1198.  
  1199.                             SerWrite("\n",1);
  1200.                             break;
  1201.  
  1202.                         case EOL_CR:
  1203.  
  1204.                             SerWrite("\r",1);
  1205.                             break;
  1206.  
  1207.                         case EOL_LFCR:
  1208.  
  1209.                             SerWrite("\n\r",2);
  1210.                             break;
  1211.  
  1212.                         case EOL_CRLF:
  1213.  
  1214.                             SerWrite("\r\n",2);
  1215.                             break;
  1216.                     }
  1217.                 }
  1218.  
  1219.                 break;
  1220.  
  1221.                 /* Stop in/output. */
  1222.  
  1223.             case CHAR_XON:
  1224.  
  1225.                 if(Config -> SerialConfig -> xONxOFF)
  1226.                     Status = STATUS_HOLDING;
  1227.  
  1228.                 if(Config -> SerialConfig -> PassThrough)
  1229.                     SerWrite(&c,1);
  1230.  
  1231.                 break;
  1232.  
  1233.                 /* Restart in/output. */
  1234.  
  1235.             case CHAR_XOFF:
  1236.  
  1237.                 if(Status == STATUS_HOLDING)
  1238.                     Status = STATUS_READY;
  1239.  
  1240.                 if(Config -> SerialConfig -> PassThrough)
  1241.                     SerWrite(&c,1);
  1242.  
  1243.                 break;
  1244.  
  1245.                 /* Any other character. */
  1246.  
  1247.             case CHAR_VANILLA:
  1248.  
  1249.                 if(Status == STATUS_HOLDING)
  1250.                 {
  1251.                     if(Bell)
  1252.                         BellSignal();
  1253.                 }
  1254.                 else
  1255.                 {
  1256.                     if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  1257.                     {
  1258.                             /* Convert special
  1259.                              * Amiga characters into
  1260.                              * alien IBM dialect.
  1261.                              */
  1262.  
  1263.                         if(IBMConversion[c])
  1264.                             SerWrite(&IBMConversion[c],1);
  1265.                         else
  1266.                             SerWrite(&c,1);
  1267.                     }
  1268.                     else
  1269.                         SerWrite(&c,1);
  1270.                 }
  1271.  
  1272.                 break;
  1273.         }
  1274.     }
  1275. }
  1276.  
  1277.     /* HandleWindow():
  1278.      *
  1279.      *    This funny part checks the window(s) for incoming
  1280.      *    user input. Menus are handled elsewhere.
  1281.      */
  1282.  
  1283. BYTE
  1284. HandleWindow()
  1285. {
  1286.     STATIC ULONG         LastSeconds,LastMicros;
  1287.  
  1288.     struct IntuiMessage    *Message;
  1289.     ULONG             IClass,Code,Qualifier,Seconds,Micros;
  1290.     LONG             MouseX,MouseY,Len,GadgetID;
  1291.     struct Gadget        *Gadget;
  1292.     UBYTE             Char,InputBuffer[257];
  1293.     struct Window        *IDCMPWindow;
  1294.     BOOLEAN             Result = FALSE,ClickAndActivate = FALSE;
  1295.  
  1296.         /* Are we reading input from the clipboard? */
  1297.  
  1298.     if(ClipInput)
  1299.     {
  1300.         WORD Len = GetClip(InputBuffer,256,TRUE);
  1301.  
  1302.         if(Len < 0)
  1303.         {
  1304.             CloseClip();
  1305.  
  1306.             ClipInput = FALSE;
  1307.  
  1308.             if(ClipXerox)
  1309.             {
  1310.                 if(Config -> ClipConfig -> InsertSuffix[0])
  1311.                     SerialCommand(Config -> ClipConfig -> InsertSuffix);
  1312.  
  1313.                 ClipXerox = FALSE;
  1314.             }
  1315.  
  1316.             ClipPrefix = FALSE;
  1317.         }
  1318.         else
  1319.         {
  1320.             if(!ClipPrefix && ClipXerox)
  1321.             {
  1322.                 if(Config -> ClipConfig -> InsertPrefix[0])
  1323.                     SerialCommand(Config -> ClipConfig -> InsertPrefix);
  1324.  
  1325.                 ClipPrefix = TRUE;
  1326.             }
  1327.  
  1328.             if(Len > 0)
  1329.                 SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
  1330.  
  1331.             Result = TRUE;
  1332.         }
  1333.     }
  1334.  
  1335.         /* Any news in the mail? */
  1336.  
  1337.     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  1338.     {
  1339.             /* A click into the window should activate it, but
  1340.              * we don't want to have the character snapping activated
  1341.              * under these conditions. In this case we rely upon
  1342.              * Intuition sending the IDCMP_ACTIVEWINDOW and
  1343.              * IDCMP_MOUSEBUTTONS event marked with the same
  1344.              * creation time stamp. Even if the Intuition
  1345.              * implementation should change no harm should
  1346.              * be done.
  1347.              */
  1348.  
  1349.         Seconds    = Message -> Seconds;
  1350.         Micros    = Message -> Micros;
  1351.  
  1352.         if(Seconds == LastSeconds && Micros == LastMicros && Message -> IDCMPWindow == Window)
  1353.         {
  1354.             if(Message -> Class == IDCMP_ACTIVEWINDOW || Message -> Class == IDCMP_MOUSEBUTTONS)
  1355.                 ClickAndActivate = TRUE;
  1356.         }
  1357.  
  1358.         LastSeconds    = Seconds;
  1359.         LastMicros    = Micros;
  1360.  
  1361.             /* Pick up the pieces. */
  1362.  
  1363.         IClass        = Message -> Class;
  1364.         Code        = Message -> Code;
  1365.         Qualifier    = Message -> Qualifier;
  1366.         Gadget        = (struct Gadget *)Message -> IAddress;
  1367.  
  1368.         MouseX        = Message -> MouseX;
  1369.         MouseY        = Message -> MouseY;
  1370.  
  1371.         IDCMPWindow    = Message -> IDCMPWindow;
  1372.  
  1373.         if(IClass == IDCMP_IDCMPUPDATE)
  1374.             GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
  1375.  
  1376.         if(IClass == IDCMP_RAWKEY)
  1377.         {
  1378.                 /* Perform key conversion. */
  1379.  
  1380.             if(XEmulatorBase)
  1381.             {
  1382.                 if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Message))
  1383.                     Char = InputBuffer[0];
  1384.             }
  1385.             else
  1386.                 Char = KeyConvert(Message,InputBuffer,&Len);
  1387.         }
  1388.  
  1389.         ReplyMsg(Message);
  1390.     }
  1391.     else
  1392.         IClass = NULL;
  1393.  
  1394.         /* Did we get any information? */
  1395.  
  1396.     if(IClass)
  1397.     {
  1398.             /* The following messages probably
  1399.              * originated from the fast! macro
  1400.              * panel.
  1401.              */
  1402.  
  1403.         if(IDCMPWindow == FastWindow)
  1404.         {
  1405.             switch(IClass)
  1406.             {
  1407.                     /* Close the window. */
  1408.  
  1409.                 case IDCMP_CLOSEWINDOW:
  1410.  
  1411.                     CloseFastWindow();
  1412.  
  1413.                     return(TRUE);
  1414.  
  1415.                     /* Window size has changed for some reason. */
  1416.  
  1417.                 case IDCMP_NEWSIZE:
  1418.  
  1419.                     RefreshFastWindow(FALSE);
  1420.  
  1421.                     return(TRUE);
  1422.  
  1423.                     /* Some gadget was invoked. */
  1424.  
  1425.                 case IDCMP_GADGETUP:
  1426.                 case IDCMP_GADGETDOWN:
  1427.  
  1428.                     GadgetID = Gadget -> GadgetID;
  1429.  
  1430.                 case IDCMP_MOUSEMOVE:
  1431.                 case IDCMP_IDCMPUPDATE:
  1432.  
  1433.                     HandleFastWindowGadget(IClass,Code,GadgetID);
  1434.  
  1435.                     return(TRUE);
  1436.             }
  1437.         }
  1438.  
  1439.             /* Status window activated? */
  1440.  
  1441.         if(IDCMPWindow == StatusWindow)
  1442.         {
  1443.             if(IClass == IDCMP_ACTIVEWINDOW && !Config -> ScreenConfig -> SplitStatus)
  1444.                 NormalCursor();
  1445.  
  1446.             if(IClass == IDCMP_CLOSEWINDOW)
  1447.             {
  1448.                 Forbid();
  1449.  
  1450.                 ClrSignal(SIG_HANDSHAKE);
  1451.  
  1452.                 Signal(StatusProcess,SIG_CLOSEWINDOW);
  1453.  
  1454.                 Wait(SIG_HANDSHAKE);
  1455.  
  1456.                 Permit();
  1457.  
  1458.                 ClearMenuStrip(StatusWindow);
  1459.                 CloseWindowSafely(StatusWindow);
  1460.  
  1461.                 StatusWindow = NULL;
  1462.             }
  1463.         }
  1464.  
  1465.             /* Main window message? */
  1466.  
  1467.         if(IDCMPWindow == Window)
  1468.         {
  1469.             switch(IClass)
  1470.             {
  1471.                 case IDCMP_INACTIVEWINDOW:
  1472.  
  1473.                     HoldClick = FALSE;
  1474.  
  1475.                     GhostCursor();
  1476.  
  1477.                     break;
  1478.  
  1479.                 case IDCMP_ACTIVEWINDOW:
  1480.  
  1481.                         // Take care of the chat gadget if necessary
  1482.  
  1483.                     ActivateChat(TRUE);
  1484.  
  1485.                     NormalCursor();
  1486.  
  1487.                     break;
  1488.  
  1489.                 case IDCMP_NEWSIZE:
  1490.  
  1491.                         /* Is a window clipping region installed? */
  1492.  
  1493.                     if(ClipRegion)
  1494.                     {
  1495.                         struct Rectangle RegionRectangle;
  1496.  
  1497.                             /* Install old region. */
  1498.  
  1499.                         InstallClipRegion(Window -> WLayer,OldRegion);
  1500.  
  1501.                             /* Fill in the clipping rectangle. */
  1502.  
  1503.                         RegionRectangle . MinX = Window -> BorderLeft;
  1504.                         RegionRectangle . MinY = Window -> BorderTop;
  1505.                         RegionRectangle . MaxX = Window -> Width - (Window -> BorderRight + 1);
  1506.                         RegionRectangle . MaxY = Window -> Height - (Window -> BorderBottom + 1);
  1507.  
  1508.                             /* Clear previous clipping region. */
  1509.  
  1510.                         ClearRegion(ClipRegion);
  1511.  
  1512.                             /* Set new clipping region. */
  1513.  
  1514.                         OrRectRegion(ClipRegion,&RegionRectangle);
  1515.  
  1516.                             /* Install new clipping region. */
  1517.  
  1518.                         OldRegion = InstallClipRegion(Window -> WLayer,ClipRegion);
  1519.                     }
  1520.  
  1521.                     ForceStatusUpdate();
  1522.  
  1523.                     HandleMenuCode(MEN_RESET_TERMINAL,Qualifier);
  1524.  
  1525.                         // Take care of the chat gadget if necessary
  1526.  
  1527.                     ActivateChat(TRUE);
  1528.  
  1529.                     TTYResize();
  1530.  
  1531.                     break;
  1532.  
  1533.                 case IDCMP_CLOSEWINDOW:
  1534.  
  1535.                     HandleMenuCode(MEN_QUIT,Qualifier);
  1536.                     break;
  1537.  
  1538.                 case IDCMP_MOUSEMOVE:
  1539.  
  1540.                     if(HoldClick)
  1541.                     {
  1542.                         if(!Marking)
  1543.                             SetMarker(ClickX,ClickY);
  1544.                         else
  1545.                         {
  1546.                             MouseX -= WindowLeft;
  1547.  
  1548.                             if(MouseX < 0)
  1549.                                 MouseX = 0;
  1550.  
  1551.                             if(MouseX > WindowWidth - 1)
  1552.                                 MouseX = WindowWidth - 1;
  1553.  
  1554.                             MouseY -= WindowTop;
  1555.  
  1556.                             if(MouseY < 0)
  1557.                                 MouseY = 0;
  1558.  
  1559.                             if(MouseY > WindowHeight - 1)
  1560.                                 MouseY = WindowHeight - 1;
  1561.  
  1562.                             MoveMarker(MouseX,MouseY);
  1563.                         }
  1564.                     }
  1565.  
  1566.                     break;
  1567.  
  1568.                 case IDCMP_MOUSEBUTTONS:
  1569.  
  1570.                     if(Code == SELECTUP)
  1571.                         ActivateChat(TRUE);
  1572.  
  1573.                     if((!ClickAndActivate || Code != SELECTDOWN) && (!XEmulatorBase || Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL))
  1574.                     {
  1575.                         if(Code == SELECTUP)
  1576.                             HoldClick = FALSE;
  1577.  
  1578.                         if(Code == SELECTDOWN)
  1579.                         {
  1580.                             MouseX -= WindowLeft;
  1581.  
  1582.                             if(MouseX < 0)
  1583.                                 MouseX = 0;
  1584.  
  1585.                             if(MouseX > WindowWidth - 1)
  1586.                                 MouseX = WindowWidth - 1;
  1587.  
  1588.                             MouseY -= WindowTop;
  1589.  
  1590.                             if(MouseY < 0)
  1591.                                 MouseY = 0;
  1592.  
  1593.                             if(MouseY > WindowHeight - 1)
  1594.                                 MouseY = WindowHeight - 1;
  1595.  
  1596.                             HoldClick = TRUE;
  1597.  
  1598.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1599.                             {
  1600.                                 WORD FirstX,FirstY;
  1601.  
  1602.                                 FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  1603.                                 FirstY = MouseY / TextFontHeight;
  1604.  
  1605.                                 if(FirstX < RasterWidth && FirstY < RasterHeight)
  1606.                                 {
  1607.                                     UBYTE Char;
  1608.  
  1609.                                     ObtainSemaphore(RasterSemaphore);
  1610.  
  1611.                                     Char = Raster[FirstY * RasterWidth + FirstX];
  1612.  
  1613.                                     ReleaseSemaphore(RasterSemaphore);
  1614.  
  1615.                                     if(Char)
  1616.                                     {
  1617.                                         SerWrite(&Char,1);
  1618.  
  1619.                                         if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1620.                                         {
  1621.                                             switch(Config -> TerminalConfig -> SendCR)
  1622.                                             {
  1623.                                                 case EOL_LF:
  1624.  
  1625.                                                     SerWrite("\n",1);
  1626.                                                     break;
  1627.  
  1628.                                                 case EOL_CR:
  1629.  
  1630.                                                     SerWrite("\r",1);
  1631.                                                     break;
  1632.  
  1633.                                                 case EOL_LFCR:
  1634.  
  1635.                                                     SerWrite("\n\r",2);
  1636.                                                     break;
  1637.  
  1638.                                                 case EOL_CRLF:
  1639.  
  1640.                                                     SerWrite("\r\n",2);
  1641.                                                     break;
  1642.                                             }
  1643.                                         }
  1644.                                     }
  1645.                                 }
  1646.  
  1647.                                 return(TRUE);
  1648.                             }
  1649.  
  1650.                             if((Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  1651.                             {
  1652.                                 WORD DeltaX,DeltaY;
  1653.  
  1654.                                 ObtainSemaphore(&TerminalSemaphore);
  1655.  
  1656.                                 DeltaX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator)  - CursorX;
  1657.                                 DeltaY = MouseY / TextFontHeight - CursorY;
  1658.  
  1659.                                 ReleaseSemaphore(&TerminalSemaphore);
  1660.  
  1661.                                 if(DeltaX || DeltaY)
  1662.                                 {
  1663.                                     if(DeltaX > 0)
  1664.                                     {
  1665.                                         DeltaX++;
  1666.  
  1667.                                         while(DeltaX--)
  1668.                                             SerWrite("\33[C",3);
  1669.                                     }
  1670.  
  1671.                                     if(DeltaX < 0)
  1672.                                     {
  1673.                                         while(DeltaX++)
  1674.                                             SerWrite("\33[D",3);
  1675.                                     }
  1676.  
  1677.                                     if(DeltaY > 0)
  1678.                                     {
  1679.                                         DeltaY++;
  1680.  
  1681.                                         while(DeltaY--)
  1682.                                             SerWrite("\33[B",3);
  1683.                                     }
  1684.  
  1685.                                     if(DeltaY < 0)
  1686.                                     {
  1687.                                         while(DeltaY++)
  1688.                                             SerWrite("\33[A",3);
  1689.                                     }
  1690.                                 }
  1691.  
  1692.                                 return(TRUE);
  1693.                             }
  1694.  
  1695.                             ReportMouse(TRUE,Window);
  1696.  
  1697.                             if(!FirstClick)
  1698.                             {
  1699.                                 ULONG CurrentSecs,CurrentMicros;
  1700.  
  1701.                                 CurrentTime(&CurrentSecs,&CurrentMicros);
  1702.  
  1703.                                 FirstClick = TRUE;
  1704.  
  1705.                                 if(ABS(ClickX - MouseX) <= TextFontWidth && ABS(ClickY - MouseY) <= TextFontHeight && DoubleClick(ClickSecs,ClickMicros,CurrentSecs,CurrentMicros))
  1706.                                 {
  1707.                                     MarkWord(ClickX,ClickY);
  1708.  
  1709.                                     return(TRUE);
  1710.                                 }
  1711.                                 else
  1712.                                 {
  1713.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1714.  
  1715.                                     FirstClick    = FALSE;
  1716.  
  1717.                                     ClickX        = MouseX;
  1718.                                     ClickY        = MouseY;
  1719.                                 }
  1720.                             }
  1721.                             else
  1722.                             {
  1723.                                 CurrentTime(&ClickSecs,&ClickMicros);
  1724.  
  1725.                                 FirstClick    = FALSE;
  1726.  
  1727.                                 ClickX        = MouseX;
  1728.                                 ClickY        = MouseY;
  1729.                             }
  1730.  
  1731.                             if(Marking)
  1732.                             {
  1733.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1734.                                     MoveMarker(MouseX,MouseY);
  1735.                                 else
  1736.                                 {
  1737.                                     DropMarker();
  1738.  
  1739.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1740.  
  1741.                                     FirstClick    = FALSE;
  1742.  
  1743.                                     ClickX        = MouseX;
  1744.                                     ClickY        = MouseY;
  1745.  
  1746.                                     ReportMouse(TRUE,Window);
  1747.                                 }
  1748.                             }
  1749.                         }
  1750.                     }
  1751.  
  1752.                     break;
  1753.             }
  1754.         }
  1755.  
  1756.             /* Now for general information. */
  1757.  
  1758.         switch(IClass)
  1759.         {
  1760.             case IDCMP_RAWKEY:
  1761.  
  1762.                     /* Take care of the numeric keypad. */
  1763.  
  1764.                 if((Qualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
  1765.                 {
  1766.                     STATIC STRPTR StringTable[22][2] =
  1767.                     {
  1768.                         "0",    "\033Op",
  1769.                         "1",    "\033Oq",
  1770.                         "2",    "\033Or",
  1771.                         "3",    "\033Os",
  1772.                         "4",    "\033Ot",
  1773.                         "5",    "\033Ou",
  1774.                         "6",    "\033Ov",
  1775.                         "7",    "\033Ow",
  1776.                         "8",    "\033Ox",
  1777.                         "9",    "\033Oy",
  1778.                         "-",    "\033Om",
  1779.                         "+",    "\033Ol",    // This should really be a comma
  1780.                         ".",    "\033On",
  1781.  
  1782.                         "(",    "\033OP",
  1783.                         "[",    "\033OP",
  1784.                         "{",    "\033OP",
  1785.                         "]",    "\033OQ",
  1786.                         ")",    "\033OQ",
  1787.                         "}",    "\033OQ",
  1788.                         "/",    "\033OR",
  1789.                         "*",    "\033OS",
  1790.  
  1791.                         "\r",    "\033OM"
  1792.                     };
  1793.  
  1794.                     STATIC struct { UBYTE Code; STRPTR String; } CodeTable[18] =
  1795.                     {
  1796.                         0x0F,    "\033Op",    // "0"
  1797.                         0x1D,    "\033Oq",    // "1"
  1798.                         0x1E,    "\033Or",    // "2"
  1799.                         0x1F,    "\033Os",    // "3"
  1800.                         0x2D,    "\033Ot",    // "4"
  1801.                         0x2E,    "\033Ou",    // "5"
  1802.                         0x2F,    "\033Ov",    // "6"
  1803.                         0x3D,    "\033Ow",    // "7"
  1804.                         0x3E,    "\033Ox",    // "8"
  1805.                         0x3F,    "\033Oy",    // "9"
  1806.                         0x4A,    "\033Om",    // "-"
  1807.                         0x5E,    "\033Ol",    // "+", but this should really be a comma
  1808.                         0x3C,    "\033On",    // "."
  1809.  
  1810.                         0x5A,    "\033OP",    // "["
  1811.                         0x5B,    "\033OQ",    // "]"
  1812.                         0x5C,    "\033OR",    // "/"
  1813.                         0x5D,    "\033OS",    // "*"
  1814.  
  1815.                         0x43,    "\033OM"    // <cr>
  1816.                     };
  1817.  
  1818.                     STRPTR    String = NULL;
  1819.                     WORD    i;
  1820.  
  1821.                     for(i = 0 ; i < 22 ; i++)
  1822.                     {
  1823.                         if(Char == StringTable[i][0][0])
  1824.                         {
  1825.                             String = StringTable[i][1];
  1826.  
  1827.                             break;
  1828.                         }
  1829.                     }
  1830.  
  1831.                     if(!String)
  1832.                     {
  1833.                         for(i = 0 ; i < 18 ; i++)
  1834.                         {
  1835.                             if(Code == CodeTable[i] . Code)
  1836.                             {
  1837.                                 String = CodeTable[i] . String;
  1838.  
  1839.                                 break;
  1840.                             }
  1841.                         }
  1842.                     }
  1843.  
  1844.                     if(String)
  1845.                     {
  1846.                         if(ClipInput)
  1847.                         {
  1848.                             CloseClip();
  1849.  
  1850.                             ClipInput = ClipXerox = ClipPrefix = FALSE;
  1851.                         }
  1852.  
  1853.                         SerWrite(String,strlen(String));
  1854.  
  1855.                         Len = 0;
  1856.                     }
  1857.                 }
  1858.  
  1859.                     /* This looks like a raw, or better, now cooked key. */
  1860.  
  1861.                 if(Len)
  1862.                 {
  1863.                     switch(CharType[Char])
  1864.                     {
  1865.                         case CHAR_HELP:
  1866.  
  1867.                             GuideDisplay(CONTEXT_MAIN);
  1868.  
  1869.                             Len = 0;
  1870.  
  1871.                             break;
  1872.  
  1873.                         case CHAR_CURSOR:
  1874.  
  1875.                             if(ClipInput)
  1876.                             {
  1877.                                 CloseClip();
  1878.  
  1879.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1880.                             }
  1881.  
  1882.                                 /* If in cursor key applications mode,
  1883.                                  * send the corresponding string.
  1884.                                  */
  1885.  
  1886.                             if(Config -> EmulationConfig -> CursorMode == KEYMODE_APPLICATION)
  1887.                             {
  1888.                                 STATIC STRPTR CursorTable[4] =
  1889.                                 {
  1890.                                     "\033OA",
  1891.                                     "\033OB",
  1892.                                     "\033OC",
  1893.                                     "\033OD"
  1894.                                 };
  1895.  
  1896.                                 SerWrite(CursorTable[Char - CUP],3);
  1897.                             }
  1898.                             else
  1899.                             {
  1900.                                 WORD QualType;
  1901.  
  1902.                                     /* Find the approriate qualifier. */
  1903.  
  1904.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1905.                                     QualType = 1;
  1906.                                 else
  1907.                                 {
  1908.                                     if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1909.                                         QualType = 2;
  1910.                                     else
  1911.                                     {
  1912.                                         if(Qualifier & IEQUALIFIER_CONTROL)
  1913.                                             QualType = 3;
  1914.                                         else
  1915.                                             QualType = 0;
  1916.                                     }
  1917.                                 }
  1918.  
  1919.                                     /* Send the corresponding string. */
  1920.  
  1921.                                 SerialCommand(CursorKeys -> Keys[QualType][Char - CUP]);
  1922.                             }
  1923.  
  1924.                             Len = 0;
  1925.  
  1926.                             break;
  1927.  
  1928.                             /* Any function key pressed? */
  1929.  
  1930.                         case CHAR_FUNCTION:
  1931.  
  1932.                             if(ClipInput)
  1933.                             {
  1934.                                 CloseClip();
  1935.  
  1936.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1937.                             }
  1938.  
  1939.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1940.                                 SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  1941.                             else
  1942.                             {
  1943.                                 if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1944.                                     SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  1945.                                 else
  1946.                                 {
  1947.                                     if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1948.                                         SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  1949.                                     else
  1950.                                         SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  1951.                                 }
  1952.                             }
  1953.  
  1954.                             Len = 0;
  1955.  
  1956.                             break;
  1957.  
  1958.                             /* Anything else? */
  1959.  
  1960.                         default:
  1961.  
  1962.                             if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  1963.                             {
  1964.                                 RememberInputText("\r",1);
  1965.  
  1966.                                 Len = 0;
  1967.  
  1968.                                 RecordingLine = TRUE;
  1969.  
  1970.                                 RememberResetInput();
  1971.  
  1972.                                 RememberOutput = FALSE;
  1973.                                 RememberInput = TRUE;
  1974.  
  1975.                                 CheckItem(MEN_RECORD_LINE,TRUE);
  1976.                             }
  1977.  
  1978.                             break;
  1979.                     }
  1980.  
  1981.                         /* Any characters to send? */
  1982.  
  1983.                     if(Len)
  1984.                         SendInputTextBuffer(InputBuffer,Len,TRUE,FALSE);
  1985.                 }
  1986.  
  1987.                 break;
  1988.  
  1989.                 /* A menu item was selected. */
  1990.  
  1991.             case IDCMP_MENUPICK:
  1992.  
  1993.                 HandleMenu(Code,Qualifier);
  1994.  
  1995.                     // Take care of the chat gadget if necessary
  1996.  
  1997.                 ActivateChat(TRUE);
  1998.  
  1999.                 break;
  2000.  
  2001.                 /* Menu help is required. */
  2002.  
  2003.             case IDCMP_MENUHELP:
  2004.  
  2005.                 if(MENUNUM(Code) == NOMENU || MENUNUM(Code) > 9 || ITEMNUM(Code) == NOITEM)
  2006.                     GuideDisplay(CONTEXT_MAIN_MENU);
  2007.                 else
  2008.                     GuideDisplay(CONTEXT_PROJECT_MEN + MENUNUM(Code));
  2009.  
  2010.                 break;
  2011.         }
  2012.  
  2013.         return(TRUE);
  2014.     }
  2015.  
  2016.     return(Result);
  2017. }
  2018.  
  2019.     /* HandleLocalDialList(BYTE ClearIt):
  2020.      *
  2021.      *    Invoke the local dialing list or clear it.
  2022.      */
  2023.  
  2024. STATIC VOID __regargs
  2025. HandleLocalDialList(BYTE ClearIt)
  2026. {
  2027.     if(Menu)
  2028.     {
  2029.         struct MenuItem *DialItem;
  2030.  
  2031.         if(DialItem = FindThisItem(Menu,FirstDialMenu))
  2032.         {
  2033.             if(Window)
  2034.                 ClearMenuStrip(Window);
  2035.  
  2036.             if(StatusWindow)
  2037.                 ClearMenuStrip(StatusWindow);
  2038.  
  2039.             if(FastWindow)
  2040.                 ClearMenuStrip(FastWindow);
  2041.  
  2042.             do
  2043.                 DialItem -> Flags &= ~CHECKED;
  2044.             while(DialItem = DialItem -> NextItem);
  2045.  
  2046.             if(Window)
  2047.                 ResetMenuStrip(Window,Menu);
  2048.  
  2049.             if(StatusWindow)
  2050.                 ResetMenuStrip(StatusWindow,Menu);
  2051.  
  2052.             if(FastWindow)
  2053.                 ResetMenuStrip(FastWindow,Menu);
  2054.         }
  2055.     }
  2056.  
  2057.     if(LocalDialList)
  2058.     {
  2059.         ObtainSemaphore(&OnlineSemaphore);
  2060.  
  2061.         if(LocalDialList -> lh_Head -> ln_Succ && !Online && !ClearIt)
  2062.         {
  2063.             ReleaseSemaphore(&OnlineSemaphore);
  2064.  
  2065.             FreeDialList(TRUE);
  2066.  
  2067.             DialList = LocalDialList;
  2068.  
  2069.             LocalDialList = NULL;
  2070.  
  2071.             LocalCount = -1;
  2072.  
  2073.             SetRedialMenu();
  2074.  
  2075.             HandleMenuCode(MEN_REDIAL,NULL);
  2076.         }
  2077.         else
  2078.         {
  2079.             ReleaseSemaphore(&OnlineSemaphore);
  2080.  
  2081.             FreeList(LocalDialList);
  2082.  
  2083.             FreeVecPooled(LocalDialList);
  2084.  
  2085.             LocalDialList = NULL;
  2086.  
  2087.             LocalCount = -1;
  2088.         }
  2089.     }
  2090. }
  2091.  
  2092.     /* HandleMenuCode(ULONG Code,ULONG Qualifier):
  2093.      *
  2094.      *    Handle each function associated with a menu code.
  2095.      */
  2096.  
  2097. VOID __regargs
  2098. HandleMenuCode(ULONG Code,ULONG Qualifier)
  2099. {
  2100.     struct FileRequester    *FileRequest;
  2101.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  2102.                 *DummyChar;
  2103.     BYTE             OldStatus = Status;
  2104.  
  2105.     BPTR             SomeFile;
  2106.     APTR             OldPtr;
  2107.  
  2108.     struct MenuItem        *Item;
  2109.  
  2110.     switch(Code)
  2111.     {
  2112.             /* Save screen as IFF-ILBM file. */
  2113.  
  2114.         case MEN_SAVE_AS_PICTURE:
  2115.  
  2116.             BlockWindows();
  2117.  
  2118.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
  2119.             {
  2120.                 if(!SaveWindow(DummyBuffer,Window))
  2121.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  2122.  
  2123.                 FreeAslRequest(FileRequest);
  2124.             }
  2125.  
  2126.             ReleaseWindows();
  2127.  
  2128.             break;
  2129.  
  2130.             /* Save screen as ASCII file. */
  2131.  
  2132.         case MEN_SAVE_AS_TEXT:
  2133.  
  2134.             BlockWindows();
  2135.  
  2136.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  2137.             {
  2138.                 LONG Error = 0;
  2139.  
  2140.                 if(GetFileSize(DummyBuffer))
  2141.                 {
  2142.                     switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2143.                     {
  2144.                         case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2145.                             break;
  2146.  
  2147.                         case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  2148.                             {
  2149.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  2150.                                 {
  2151.                                     Close(SomeFile);
  2152.  
  2153.                                     SomeFile = NULL;
  2154.                                 }
  2155.                             }
  2156.  
  2157.                             break;
  2158.  
  2159.                         case 0:    SomeFile = ~0;
  2160.                             break;
  2161.                     }
  2162.                 }
  2163.                 else
  2164.                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2165.  
  2166.                 if(SomeFile)
  2167.                 {
  2168.                     if(SomeFile != ~0)
  2169.                     {
  2170.                         LONG     i,j;
  2171.                         UBYTE    *Buffer;
  2172.  
  2173.                         for(i = 0 ; i < RasterHeight ; i++)
  2174.                         {
  2175.                             Buffer = &Raster[i * RasterWidth];
  2176.  
  2177.                             j = RasterWidth - 1;
  2178.  
  2179.                             while(j >= 0 && Buffer[j] == ' ')
  2180.                                 j--;
  2181.  
  2182.                             if(j >= 0)
  2183.                             {
  2184.                                 SetIoErr(0);
  2185.  
  2186.                                 if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
  2187.                                 {
  2188.                                     Error = IoErr();
  2189.  
  2190.                                     break;
  2191.                                 }
  2192.                             }
  2193.  
  2194.                             SetIoErr(0);
  2195.  
  2196.                             if(FWrite(SomeFile,"\n",1,1) < 1)
  2197.                             {
  2198.                                 Error = IoErr();
  2199.  
  2200.                                 break;
  2201.                             }
  2202.                         }
  2203.  
  2204.                         Close(SomeFile);
  2205.  
  2206.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  2207.  
  2208.                         if(Config -> MiscConfig -> CreateIcons)
  2209.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  2210.                     }
  2211.                 }
  2212.                 else
  2213.                     Error = IoErr();
  2214.  
  2215.                 if(Error)
  2216.                     ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
  2217.  
  2218.                 FreeAslRequest(FileRequest);
  2219.             }
  2220.  
  2221.             ReleaseWindows();
  2222.  
  2223.             break;
  2224.  
  2225.             /* Print the screen (pure ASCII). */
  2226.  
  2227.         case MEN_PRINT_SCREEN:
  2228.  
  2229.             BlockWindows();
  2230.  
  2231.             if(RasterEnabled)
  2232.                 PrintSomething(PRINT_SCREEN);
  2233.             else
  2234.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2235.  
  2236.             ReleaseWindows();
  2237.  
  2238.             break;
  2239.  
  2240.             /* Print the screen (graphics). */
  2241.  
  2242.         case MEN_PRINT_SCREEN_AS_GFX:
  2243.  
  2244.             BlockWindows();
  2245.  
  2246.             PrintScreenGfx();
  2247.  
  2248.             ReleaseWindows();
  2249.  
  2250.             break;
  2251.  
  2252.             /* Print the clipboard contents. */
  2253.  
  2254.         case MEN_PRINT_CLIP:
  2255.  
  2256.             BlockWindows();
  2257.  
  2258.             PrintSomething(PRINT_CLIP);
  2259.  
  2260.             ReleaseWindows();
  2261.  
  2262.             break;
  2263.  
  2264.             /* Open/close the terminal capture file. */
  2265.  
  2266.         case MEN_CAPTURE_TO_FILE:
  2267.  
  2268.             if(FileCapture)
  2269.                 CloseFileCapture();
  2270.             else
  2271.                 OpenFileCapture();
  2272.  
  2273.             CheckItem(MEN_CAPTURE_TO_FILE,FileCapture != NULL);
  2274.  
  2275.             break;
  2276.  
  2277.             /* Start/terminate the printer
  2278.              * capture.
  2279.              */
  2280.  
  2281.         case MEN_CAPTURE_TO_PRINTER:
  2282.  
  2283.             if(PrinterCapture)
  2284.                 ClosePrinterCapture(TRUE);
  2285.             else
  2286.                 OpenPrinterCapture(FALSE);
  2287.  
  2288.             CheckItem(MEN_CAPTURE_TO_PRINTER,PrinterCapture != NULL);
  2289.  
  2290.             break;
  2291.  
  2292.             /* Iconify the program. */
  2293.  
  2294.         case MEN_ICONIFY:
  2295.  
  2296.             if(Config -> MiscConfig -> ProtectiveMode)
  2297.             {
  2298.                 ObtainSemaphore(&OnlineSemaphore);
  2299.  
  2300.                 if(Online && Config -> MiscConfig -> ReleaseDevice && !(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  2301.                 {
  2302.                     ReleaseSemaphore(&OnlineSemaphore);
  2303.  
  2304.                     BlockWindows();
  2305.  
  2306.                     if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2307.                     {
  2308.                         ReleaseWindows();
  2309.  
  2310.                         break;
  2311.                     }
  2312.  
  2313.                     ReleaseWindows();
  2314.                 }
  2315.                 else
  2316.                     ReleaseSemaphore(&OnlineSemaphore);
  2317.             }
  2318.  
  2319.             DoIconify = TRUE;
  2320.  
  2321.             break;
  2322.  
  2323.             /* Say who we are. */
  2324.  
  2325.         case MEN_ABOUT:
  2326.  
  2327.             BlockWindows();
  2328. #ifdef DATAFEED
  2329.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2330.             {
  2331.                 STATIC UBYTE LastFile[40],LastPath[256];
  2332.  
  2333.                 extern BPTR DataFeed;
  2334.  
  2335.                 if(DataFeed)
  2336.                 {
  2337.                     Close(DataFeed);
  2338.  
  2339.                     DataFeed = NULL;
  2340.                 }
  2341.  
  2342.                 if(FileRequest = GetFile(Window,"Select terminal test file",LastPath,LastFile,DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
  2343.                 {
  2344.                     if(GetFileSize(DummyBuffer))
  2345.                     {
  2346.                         if(DataFeed = Open(DummyBuffer,MODE_OLDFILE))
  2347.                         {
  2348.                             strcpy(LastFile,FileRequest -> fr_File);
  2349.                             strcpy(LastPath,FileRequest -> fr_Drawer);
  2350.  
  2351.                             if(Kick30)
  2352.                                 SetVBuf(DataFeed,NULL,2,8192);
  2353.                         }
  2354.                     }
  2355.  
  2356.                     FreeAslRequest(FileRequest);
  2357.                 }
  2358.             }
  2359.             else
  2360. #endif    /* DATAFEED */
  2361.  
  2362.             ShowAbout(FALSE);
  2363.  
  2364.             ReleaseWindows();
  2365.  
  2366.             break;
  2367.  
  2368.             /* Terminate the program. */
  2369.  
  2370.         case MEN_QUIT:
  2371.  
  2372.             if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
  2373.                 MainTerminated = TRUE;
  2374.             else
  2375.             {
  2376.                 STRPTR    Buffer;
  2377.                 LONG    OldLen,Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
  2378.  
  2379.                 OldLen = Len;
  2380.  
  2381.                 ObtainSemaphore(&OnlineSemaphore);
  2382.  
  2383.                 if(Online)
  2384.                     Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
  2385.  
  2386.                 ReleaseSemaphore(&OnlineSemaphore);
  2387.  
  2388.                 if(BufferChanged)
  2389.                     Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
  2390.  
  2391.                 if(ConfigChanged)
  2392.                     Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
  2393.  
  2394.                 if(PhonebookChanged)
  2395.                     Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
  2396.  
  2397.                 if(TranslationChanged)
  2398.                     Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
  2399.  
  2400.                 if(MacroChanged)
  2401.                     Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
  2402.  
  2403.                 if(CursorKeysChanged)
  2404.                     Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
  2405.  
  2406.                 if(FastMacrosChanged)
  2407.                     Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
  2408.  
  2409.                 if(HotkeysChanged)
  2410.                     Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
  2411.  
  2412.                 if(SpeechChanged)
  2413.                     Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
  2414.  
  2415.                 if(SoundChanged)
  2416.                     Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
  2417.  
  2418.                 BlockWindows();
  2419.  
  2420.                 OldPtr = ThisProcess -> pr_WindowPtr;
  2421.  
  2422.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  2423.  
  2424.                 if(OldLen != Len)
  2425.                 {
  2426.                     if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
  2427.                     {
  2428.                         SPrintf(Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
  2429.  
  2430.                         ObtainSemaphore(&OnlineSemaphore);
  2431.  
  2432.                         if(Online)
  2433.                         {
  2434.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
  2435.  
  2436.                             strcat(Buffer,SharedBuffer);
  2437.                         }
  2438.  
  2439.                         ReleaseSemaphore(&OnlineSemaphore);
  2440.  
  2441.                         if(BufferChanged)
  2442.                         {
  2443.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
  2444.  
  2445.                             strcat(Buffer,SharedBuffer);
  2446.                         }
  2447.  
  2448.                         if(ConfigChanged)
  2449.                         {
  2450.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
  2451.  
  2452.                             strcat(Buffer,SharedBuffer);
  2453.                         }
  2454.  
  2455.                         if(PhonebookChanged)
  2456.                         {
  2457.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
  2458.  
  2459.                             strcat(Buffer,SharedBuffer);
  2460.                         }
  2461.  
  2462.                         if(TranslationChanged)
  2463.                         {
  2464.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
  2465.  
  2466.                             strcat(Buffer,SharedBuffer);
  2467.                         }
  2468.  
  2469.                         if(MacroChanged)
  2470.                         {
  2471.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
  2472.  
  2473.                             strcat(Buffer,SharedBuffer);
  2474.                         }
  2475.  
  2476.                         if(CursorKeysChanged)
  2477.                         {
  2478.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
  2479.  
  2480.                             strcat(Buffer,SharedBuffer);
  2481.                         }
  2482.  
  2483.                         if(FastMacrosChanged)
  2484.                         {
  2485.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
  2486.  
  2487.                             strcat(Buffer,SharedBuffer);
  2488.                         }
  2489.  
  2490.                         if(HotkeysChanged)
  2491.                         {
  2492.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
  2493.  
  2494.                             strcat(Buffer,SharedBuffer);
  2495.                         }
  2496.  
  2497.                         if(SpeechChanged)
  2498.                         {
  2499.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
  2500.  
  2501.                             strcat(Buffer,SharedBuffer);
  2502.                         }
  2503.  
  2504.                         if(MyEasyRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2505.                             MainTerminated = TRUE;
  2506.  
  2507.                         FreeVecPooled(Buffer);
  2508.                     }
  2509.                     else
  2510.                         MainTerminated = TRUE;
  2511.                 }
  2512.                 else
  2513.                     MainTerminated = TRUE;
  2514.  
  2515.                 ThisProcess -> pr_WindowPtr = OldPtr;
  2516.  
  2517.                 ReleaseWindows();
  2518.             }
  2519.  
  2520.             break;
  2521.  
  2522.             /* Feed the contents of the clipboard
  2523.              * into the input stream.
  2524.              */
  2525.  
  2526.         case MEN_PASTE:
  2527.  
  2528.             if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
  2529.             {
  2530.                 ClipInput = TRUE;
  2531.  
  2532.                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2533.                     ClipXerox = TRUE;
  2534.             }
  2535.             else
  2536.                 ClipInput = FALSE;
  2537.  
  2538.             break;
  2539.  
  2540.         case MEN_COPY:
  2541.  
  2542.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2543.                 ClipMarker(TRUE);
  2544.             else
  2545.                 ClipMarker(FALSE);
  2546.  
  2547.             break;
  2548.  
  2549.         case MEN_CLEAR:
  2550.  
  2551.             DropMarker();
  2552.             break;
  2553.  
  2554.             /* Execute an AmigaDOS command. */
  2555.  
  2556.         case MEN_EXECUTE_DOS_COMMAND:
  2557.  
  2558.             BlockWindows();
  2559.  
  2560.                 /* Enter the name of the command. */
  2561.  
  2562.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
  2563.                 SendAmigaDOSCommand(AmigaDOSCommandBuffer);
  2564.  
  2565.             ReleaseWindows();
  2566.  
  2567.             break;
  2568.  
  2569.             /* Execute an ARexx script command. */
  2570.  
  2571.         case MEN_EXECUTE_REXX_COMMAND:
  2572.  
  2573.             BlockWindows();
  2574.  
  2575.                 /* Get the rexx file name/program. */
  2576.  
  2577.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
  2578.                 SendARexxCommand(ARexxCommandBuffer,TRUE);
  2579.  
  2580.             ReleaseWindows();
  2581.  
  2582.             break;
  2583.  
  2584.             /* Turn recording on/off. */
  2585.  
  2586.         case MEN_RECORD:
  2587.  
  2588.             if(GetItem(MEN_RECORD))
  2589.             {
  2590.                 if(!Recording)
  2591.                 {
  2592.                     if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
  2593.                     {
  2594.                         RememberResetOutput();
  2595.                         RememberResetInput();
  2596.  
  2597.                         RememberOutput = TRUE;
  2598.  
  2599.                         Recording = TRUE;
  2600.                         RecordingLine = FALSE;
  2601.  
  2602.                         OnItem(MEN_RECORD_LINE);
  2603.                     }
  2604.                 }
  2605.             }
  2606.             else
  2607.             {
  2608.                 if(Recording)
  2609.                 {
  2610.                     FinishRecord();
  2611.  
  2612.                     RememberOutput = FALSE;
  2613.                     RememberInput = FALSE;
  2614.  
  2615.                     Recording = FALSE;
  2616.                     RecordingLine = FALSE;
  2617.  
  2618.                     OffItem(MEN_RECORD_LINE);
  2619.  
  2620.                     Status = STATUS_READY;
  2621.                 }
  2622.             }
  2623.  
  2624.             break;
  2625.  
  2626.         case MEN_RECORD_LINE:
  2627.  
  2628.             if(Recording)
  2629.             {
  2630.                 if(GetItem(MEN_RECORD))
  2631.                 {
  2632.                     if(!RecordingLine)
  2633.                     {
  2634.                         RecordingLine = TRUE;
  2635.  
  2636.                         RememberResetInput();
  2637.  
  2638.                         RememberOutput = FALSE;
  2639.                         RememberInput = TRUE;
  2640.                     }
  2641.                 }
  2642.                 else
  2643.                 {
  2644.                     if(RecordingLine)
  2645.                     {
  2646.                         RememberSpill();
  2647.  
  2648.                         RecordingLine = FALSE;
  2649.  
  2650.                         RememberOutput = TRUE;
  2651.                         RememberInput = FALSE;
  2652.                     }
  2653.                 }
  2654.             }
  2655.  
  2656.             break;
  2657.  
  2658.         case MEN_DISABLE_TRAPS:
  2659.  
  2660.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2661.             {
  2662.                 ObtainSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2663.  
  2664.                 if(!(Item -> Flags & CHECKED) && GenericListTable[GLIST_TRAP] -> ListHeader . mlh_Head -> mln_Succ)
  2665.                     WatchTraps = TRUE;
  2666.                 else
  2667.                     WatchTraps = FALSE;
  2668.  
  2669.                 ReleaseSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2670.             }
  2671.  
  2672.             break;
  2673.  
  2674.             /* Edit the trap settings? */
  2675.  
  2676.         case MEN_EDIT_TRAPS:
  2677.  
  2678.             BlockWindows();
  2679.  
  2680.             TrapPanel();
  2681.  
  2682.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2683.             {
  2684.                 if(WatchTraps)
  2685.                     Item -> Flags &= ~CHECKED;
  2686.                 else
  2687.                     Item -> Flags |= CHECKED;
  2688.             }
  2689.  
  2690.             ReleaseWindows();
  2691.  
  2692.             break;
  2693.  
  2694.             /* Set the name we will use to open the
  2695.              * default console output window for
  2696.              * AmigaDOS commands and ARexx scripts.
  2697.              */
  2698.  
  2699.         case MEN_SET_CONSOLE:
  2700.  
  2701.             BlockWindows();
  2702.  
  2703.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
  2704.                 SetEnvDOS("TERMWINDOW",WindowName);
  2705.  
  2706.             ReleaseWindows();
  2707.  
  2708.             break;
  2709.  
  2710.             /* Open the phonebook and dial the
  2711.              * list of entries the user will select.
  2712.              */
  2713.  
  2714.         case MEN_PHONEBOOK:
  2715.  
  2716.             BlockWindows();
  2717.  
  2718.             HandleLocalDialList(TRUE);
  2719.  
  2720.             while(PhonePanel())
  2721.             {
  2722.                 if(!DialPanel())
  2723.                 {
  2724.                     Status = OldStatus;
  2725.  
  2726.                     break;
  2727.                 }
  2728.  
  2729.                 Status = OldStatus;
  2730.             }
  2731.  
  2732.             SetRedialMenu();
  2733.  
  2734.             ReleaseWindows();
  2735.  
  2736.             break;
  2737.  
  2738.             /* Redial those dial list entries which
  2739.              * we were unable to connect.
  2740.              */
  2741.  
  2742.         case MEN_REDIAL:
  2743.  
  2744.             BlockWindows();
  2745.  
  2746.                 /* If the modem is still online, provide help. */
  2747.  
  2748.             if(!AskDial(Window))
  2749.             {
  2750.                 ReleaseWindows();
  2751.                 break;
  2752.             }
  2753.  
  2754.             HandleLocalDialList(TRUE);
  2755.  
  2756.             do
  2757.             {
  2758.                 if(!DialPanel())
  2759.                 {
  2760.                     Status = OldStatus;
  2761.  
  2762.                     break;
  2763.                 }
  2764.  
  2765.                 Status = OldStatus;
  2766.             }
  2767.             while(PhonePanel());
  2768.  
  2769.             SetRedialMenu();
  2770.  
  2771.             ReleaseWindows();
  2772.  
  2773.             break;
  2774.  
  2775.             /* Dial a single number. */
  2776.  
  2777.         case MEN_DIAL_NUMBER:
  2778.  
  2779.             BlockWindows();
  2780.  
  2781.                 /* If the modem is still online, provide help. */
  2782.  
  2783.             if(!AskDial(Window))
  2784.             {
  2785.                 ReleaseWindows();
  2786.                 break;
  2787.             }
  2788.  
  2789.             HandleLocalDialList(TRUE);
  2790.  
  2791.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DialNumberBuffer))
  2792.             {
  2793.                 if(DialNumberBuffer[0])
  2794.                 {
  2795.                     struct List *LocalList;
  2796.  
  2797.                     if(LocalList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  2798.                     {
  2799.                         struct PhoneNode    *DialNode;
  2800.                         LONG             Len = strlen(DialNumberBuffer);
  2801.  
  2802.                         NewList(LocalList);
  2803.  
  2804.                         if(DialNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY|MEMF_CLEAR))
  2805.                         {
  2806.                             DialNode -> VanillaNode . ln_Name = (char *)(DialNode + 1);
  2807.  
  2808.                             strcpy(DialNode -> VanillaNode . ln_Name,DialNumberBuffer);
  2809.  
  2810.                             AddTail(LocalList,&DialNode -> VanillaNode);
  2811.  
  2812.                             FreeDialList(TRUE);
  2813.  
  2814.                             DialList = LocalList;
  2815.  
  2816.                             DialPanel();
  2817.  
  2818.                             Status = OldStatus;
  2819.                         }
  2820.                         else
  2821.                             FreeVecPooled(LocalList);
  2822.                     }
  2823.                 }
  2824.             }
  2825.  
  2826.             SetRedialMenu();
  2827.  
  2828.             ReleaseWindows();
  2829.  
  2830.             break;
  2831.  
  2832.             /* Send a break across the serial line. */
  2833.  
  2834.         case MEN_SEND_BREAK:
  2835.  
  2836.             SendBreak();
  2837.             break;
  2838.  
  2839.             /* Hang up the phone line. */
  2840.  
  2841.         case MEN_HANG_UP:
  2842.  
  2843.             FullHangup(FALSE);
  2844.  
  2845.             break;
  2846.  
  2847.             /* Wait a bit... */
  2848.  
  2849.         case MEN_WAIT:
  2850.         {
  2851.             struct Window        *ReqWindow;
  2852.             struct EasyStruct     Easy;
  2853.  
  2854.             Easy . es_StructSize    = sizeof(struct EasyStruct);
  2855.             Easy . es_Flags        = NULL;
  2856.             Easy . es_Title        = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  2857.             Easy . es_GadgetFormat    = (UBYTE *)LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  2858.             Easy . es_TextFormat    = (UBYTE *)LocaleString(MSG_TERMMAIN_WAITING_TXT);
  2859.  
  2860.             BlockWindows();
  2861.  
  2862.             if(ReqWindow = BuildEasyRequest(Window,&Easy,IDCMP_RAWKEY,NULL))
  2863.             {
  2864.                 ULONG    Signals;
  2865.                 BYTE    Done = FALSE;
  2866.  
  2867.                     /* Don't echo serial output. */
  2868.  
  2869.                 Quiet = TRUE;
  2870.  
  2871.                 do
  2872.                 {
  2873.                     SerWrite(" \b",2);
  2874.  
  2875.                     HandleSerial();
  2876.  
  2877.                     StartTime(1,0);
  2878.  
  2879.                     Signals = Wait(SIG_TIMER | PORTMASK(ReqWindow -> UserPort));
  2880.  
  2881.                     if(Signals & SIG_TIMER)
  2882.                         WaitIO(TimeRequest);
  2883.  
  2884.                     if(Signals & PORTMASK(ReqWindow -> UserPort))
  2885.                     {
  2886.                         LONG    Result;
  2887.                         ULONG    IDCMP = NULL;
  2888.  
  2889.                         Result = SysReqHandler(ReqWindow,&IDCMP,FALSE);
  2890.  
  2891.                         if(Result == 0 || (Result == -2 && !(IDCMP & IDCMP_RAWKEY)))
  2892.                         {
  2893.                             if(!CheckIO(TimeRequest))
  2894.                                 AbortIO(TimeRequest);
  2895.  
  2896.                             WaitIO(TimeRequest);
  2897.  
  2898.                             Done = TRUE;
  2899.                         }
  2900.                     }
  2901.                 }
  2902.                 while(!Done);
  2903.  
  2904.                 Quiet = FALSE;
  2905.  
  2906.                 FreeSysRequest(ReqWindow);
  2907.             }
  2908.  
  2909.             ReleaseWindows();
  2910.         }
  2911.  
  2912.         break;
  2913.  
  2914.             /* Flush the serial buffers. */
  2915.  
  2916.         case MEN_FLUSH_BUFFER:
  2917.  
  2918.             ClearSerial();
  2919.  
  2920.             RestartSerial(FALSE);
  2921.  
  2922.             break;
  2923.  
  2924.             /* Release the serial device for other
  2925.              * applications.
  2926.              */
  2927.  
  2928.         case MEN_RELEASE_DEVICE:
  2929.  
  2930.             ReleaseSerial = TRUE;
  2931.             break;
  2932.  
  2933.         case MEN_UPLOAD_ASCII:
  2934.  
  2935.             BlockWindows();
  2936.  
  2937.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  2938.             {
  2939.                 BinaryTransfer = FALSE;
  2940.  
  2941.                 StartXprSend(TRANSFER_ASCII,TRUE);
  2942.  
  2943.                 BinaryTransfer = TRUE;
  2944.             }
  2945.  
  2946.             ResetProtocol();
  2947.  
  2948.             ReleaseWindows();
  2949.  
  2950.             break;
  2951.  
  2952.         case MEN_DOWNLOAD_ASCII:
  2953.  
  2954.             BlockWindows();
  2955.  
  2956.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
  2957.             {
  2958.                 BinaryTransfer = FALSE;
  2959.  
  2960.                 StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  2961.  
  2962.                 BinaryTransfer = TRUE;
  2963.             }
  2964.  
  2965.             ResetProtocol();
  2966.  
  2967.             ReleaseWindows();
  2968.  
  2969.             break;
  2970.  
  2971.         case MEN_UPLOAD_TEXT:
  2972.  
  2973.             BlockWindows();
  2974.  
  2975.             if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  2976.             {
  2977.                 BinaryTransfer = FALSE;
  2978.  
  2979.                 StartXprSend(TRANSFER_TEXT,TRUE);
  2980.  
  2981.                 BinaryTransfer = TRUE;
  2982.             }
  2983.  
  2984.             ResetProtocol();
  2985.  
  2986.             ReleaseWindows();
  2987.  
  2988.             break;
  2989.  
  2990.         case MEN_DOWNLOAD_TEXT:
  2991.  
  2992.             BlockWindows();
  2993.  
  2994.             if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
  2995.             {
  2996.                 BinaryTransfer = FALSE;
  2997.  
  2998.                 StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  2999.  
  3000.                 BinaryTransfer = TRUE;
  3001.             }
  3002.  
  3003.             ResetProtocol();
  3004.  
  3005.             ReleaseWindows();
  3006.  
  3007.             break;
  3008.  
  3009.             /* Edit and transfer a file. */
  3010.  
  3011.         case MEN_EDIT_AND_UPLOAD_TEXT:
  3012.  
  3013.             BlockWindows();
  3014.  
  3015.             if(!Config -> PathConfig -> Editor[0])
  3016.                 GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config -> PathConfig -> Editor);
  3017.  
  3018.             if(Config -> PathConfig -> Editor[0])
  3019.             {
  3020.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT),TRUE))
  3021.                 {
  3022.                     UBYTE CompoundName[512];
  3023.  
  3024.                     strcpy(CompoundName,Config -> PathConfig -> Editor);
  3025.                     strcat(CompoundName," \"");
  3026.                     strcat(CompoundName,DummyBuffer);
  3027.                     strcat(CompoundName,"\"");
  3028.  
  3029.                     LaunchCommand(CompoundName);
  3030.  
  3031.                     BumpWindow(Window);
  3032.  
  3033.                     FreeAslRequest(FileRequest);
  3034.  
  3035.                     if(GetFileSize(DummyBuffer))
  3036.                     {
  3037.                         BinaryTransfer = FALSE;
  3038.  
  3039.                         switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  3040.                         {
  3041.                             case 1:    if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  3042.                                     SendTextFile(TRANSFER_ASCII,DummyBuffer);
  3043.  
  3044.                                 ResetProtocol();
  3045.  
  3046.                                 break;
  3047.  
  3048.                             case 2:    if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  3049.                                     SendTextFile(TRANSFER_TEXT,DummyBuffer);
  3050.  
  3051.                                 ResetProtocol();
  3052.  
  3053.                                 break;
  3054.                         }
  3055.  
  3056.                         BinaryTransfer = TRUE;
  3057.                     }
  3058.                 }
  3059.             }
  3060.  
  3061.             ReleaseWindows();
  3062.             break;
  3063.  
  3064.         case MEN_UPLOAD_BINARY:
  3065.  
  3066.             BlockWindows();
  3067.  
  3068.             if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
  3069.             {
  3070.                 BinaryTransfer = TRUE;
  3071.  
  3072.                 StartXprSend(TRANSFER_BINARY,TRUE);
  3073.             }
  3074.  
  3075.             ResetProtocol();
  3076.  
  3077.             ReleaseWindows();
  3078.  
  3079.             break;
  3080.  
  3081.             /* Download some files. */
  3082.  
  3083.         case MEN_DOWNLOAD_BINARY:
  3084.  
  3085.             BlockWindows();
  3086.  
  3087.             if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
  3088.             {
  3089.                 BinaryTransfer = TRUE;
  3090.  
  3091.                 StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  3092.             }
  3093.  
  3094.             ResetProtocol();
  3095.  
  3096.             ReleaseWindows();
  3097.  
  3098.             break;
  3099.  
  3100.             /* Clear the contents of the scrollback
  3101.              * buffer.
  3102.              */
  3103.  
  3104.         case MEN_CLEAR_BUFFER:
  3105.  
  3106.             if(Lines)
  3107.             {
  3108.                 BlockWindows();
  3109.  
  3110.                 if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
  3111.                 {
  3112.                     FreeBuffer();
  3113.  
  3114.                     TerminateBuffer();
  3115.                 }
  3116.                 else
  3117.                 {
  3118.                     if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  3119.                     {
  3120.                         FreeBuffer();
  3121.  
  3122.                         TerminateBuffer();
  3123.                     }
  3124.                 }
  3125.  
  3126.                 ReleaseWindows();
  3127.             }
  3128.  
  3129.             break;
  3130.  
  3131.             /* Display the scrollback buffer.
  3132.              * Notify the scrollback task or
  3133.              * fire it off if approriate.
  3134.              */
  3135.  
  3136.         case MEN_DISPLAY_BUFFER:
  3137.  
  3138.             if(!LaunchBuffer())
  3139.             {
  3140.                 BlockWindows();
  3141.  
  3142.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3143.  
  3144.                 ReleaseWindows();
  3145.             }
  3146.  
  3147.             break;
  3148.  
  3149.             /* Close the buffer display. */
  3150.  
  3151.         case MEN_CLOSE_BUFFER:
  3152.  
  3153.             if(BufferTask)
  3154.             {
  3155.                 Forbid();
  3156.  
  3157.                 Signal(BufferTask,SIG_KILL);
  3158.  
  3159.                 ClrSignal(SIG_HANDSHAKE);
  3160.  
  3161.                 Wait(SIG_HANDSHAKE);
  3162.  
  3163.                 Permit();
  3164.             }
  3165.  
  3166.             break;
  3167.  
  3168.             /* Is the buffer to be frozen? */
  3169.  
  3170.         case MEN_FREEZE_BUFFER:
  3171.  
  3172.             if(Item = FindThisItem(Menu,MEN_FREEZE_BUFFER))
  3173.             {
  3174.                 if(Item -> Flags & CHECKED)
  3175.                     BufferFrozen = TRUE;
  3176.                 else
  3177.                     BufferFrozen = FALSE;
  3178.  
  3179.                 Forbid();
  3180.  
  3181.                 ConOutputUpdate();
  3182.  
  3183.                 Permit();
  3184.             }
  3185.  
  3186.             break;
  3187.  
  3188.             /* Load the buffer contents from a file. */
  3189.  
  3190.         case MEN_OPEN_BUFFER:
  3191.  
  3192.             BlockWindows();
  3193.  
  3194.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
  3195.             {
  3196.                 if(GetFileSize(DummyBuffer))
  3197.                 {
  3198.                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  3199.                     {
  3200.                         if(Lines)
  3201.                         {
  3202.                             switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  3203.                             {
  3204.                                 case 1:    FreeBuffer();
  3205.                                     break;
  3206.  
  3207.                                 case 2:    break;
  3208.  
  3209.                                 case 0:    Close(SomeFile);
  3210.                                     SomeFile = NULL;
  3211.                                     break;
  3212.                             }
  3213.                         }
  3214.  
  3215.                         if(SomeFile)
  3216.                         {
  3217.                             LONG Len;
  3218.  
  3219.                             LineRead(NULL,NULL,NULL);
  3220.  
  3221.                             while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
  3222.                                 CaptureParser(DummyBuffer,Len,AddLine);
  3223.  
  3224.                             Close(SomeFile);
  3225.  
  3226.                             BufferChanged = TRUE;
  3227.                         }
  3228.                     }
  3229.                     else
  3230.                         ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  3231.                 }
  3232.  
  3233.                 FreeAslRequest(FileRequest);
  3234.             }
  3235.  
  3236.             ReleaseWindows();
  3237.             break;
  3238.  
  3239.             /* Save the contents of the scrollback
  3240.              * buffer to a file (line by line).
  3241.              */
  3242.  
  3243.         case MEN_SAVE_BUFFER_AS:
  3244.  
  3245.             BlockWindows();
  3246.  
  3247.             if(!Lines || !BufferLines)
  3248.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3249.             else
  3250.             {
  3251.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),Config -> CaptureConfig -> BufferPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  3252.                 {
  3253.                     LONG Error = 0;
  3254.  
  3255.                     SomeFile = NULL;
  3256.  
  3257.                         /* If the file we are about
  3258.                          * to create already exists,
  3259.                          * ask the user whether we are
  3260.                          * to create, append or skip
  3261.                          * the file.
  3262.                          */
  3263.  
  3264.                     if(GetFileSize(DummyBuffer))
  3265.                     {
  3266.                         switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  3267.                         {
  3268.                             case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3269.                                 break;
  3270.  
  3271.                             case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  3272.                                 {
  3273.                                     if(Seek(SomeFile,0,OFFSET_END) == -1)
  3274.                                     {
  3275.                                         Close(SomeFile);
  3276.  
  3277.                                         SomeFile = NULL;
  3278.                                     }
  3279.                                 }
  3280.  
  3281.                                 break;
  3282.                         }
  3283.                     }
  3284.                     else
  3285.                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3286.  
  3287.                     if(SomeFile)
  3288.                     {
  3289.                         LONG i,Len;
  3290.  
  3291.                             /* Obtain the semaphore required
  3292.                              * to gain access to the line buffer
  3293.                              */
  3294.  
  3295.                         ObtainSemaphore(BufferSemaphore);
  3296.  
  3297.                         for(i = 0 ; i < Lines ; i++)
  3298.                         {
  3299.                             Len = BufferLines[i][-1];
  3300.  
  3301.                             if(Len)
  3302.                             {
  3303.                                 SetIoErr(0);
  3304.  
  3305.                                 if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
  3306.                                 {
  3307.                                     Error = IoErr();
  3308.  
  3309.                                     break;
  3310.                                 }
  3311.                             }
  3312.  
  3313.                             SetIoErr(0);
  3314.  
  3315.                             if(FPrintf(SomeFile,"\n") < 1)
  3316.                             {
  3317.                                 Error = IoErr();
  3318.  
  3319.                                 break;
  3320.                             }
  3321.                         }
  3322.  
  3323.                         ReleaseSemaphore(BufferSemaphore);
  3324.  
  3325.                         Close(SomeFile);
  3326.  
  3327.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  3328.  
  3329.                         if(Config -> MiscConfig -> CreateIcons)
  3330.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  3331.  
  3332.                         BufferChanged = FALSE;
  3333.                     }
  3334.                     else
  3335.                         Error = IoErr();
  3336.  
  3337.                     if(Error)
  3338.                         ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3339.  
  3340.                     FreeAslRequest(FileRequest);
  3341.                 }
  3342.             }
  3343.  
  3344.             ReleaseWindows();
  3345.  
  3346.             break;
  3347.  
  3348.             /* Simply clear the screen and move the
  3349.              * cursor to its home position.
  3350.              */
  3351.  
  3352.         case MEN_CLEAR_SCREEN:
  3353.  
  3354.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3355.                 XEmulatorClearConsole(XEM_IO);
  3356.             else
  3357.             {
  3358.                 DropMarker();
  3359.  
  3360.                 ConBypass("\033[2J\033[H",-1);
  3361.             }
  3362.  
  3363.             break;
  3364.  
  3365.             /* Reset the current text rendering font. */
  3366.  
  3367.         case MEN_RESET_FONT:
  3368.  
  3369.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3370.                 XEmulatorResetCharset(XEM_IO);
  3371.             else
  3372.             {
  3373.                 DropMarker();
  3374.  
  3375.                 CurrentFont = TextFont;
  3376.  
  3377.                 SetFont(RPort,CurrentFont);
  3378.  
  3379.                 ConOutputUpdate();
  3380.             }
  3381.  
  3382.             break;
  3383.  
  3384.             /* Reset the display styles and restore
  3385.              * the colours.
  3386.              */
  3387.  
  3388.         case MEN_RESET_STYLES:
  3389.  
  3390.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3391.                 XEmulatorResetTextStyles(XEM_IO);
  3392.             else
  3393.             {
  3394.                 DropMarker();
  3395.  
  3396.                 ConBypass("\033[0m",-1);
  3397.  
  3398.                 ObtainSemaphore(&TerminalSemaphore);
  3399.  
  3400.                 ClearCursor();
  3401.  
  3402.                 CurrentCharWidth = SCALE_NORMAL;
  3403.  
  3404.                 if(!Config -> EmulationConfig -> LockColour)
  3405.                 {
  3406.                     ForegroundPen = GetPenIndex(SafeTextPen);
  3407.                     BackgroundPen = 0;
  3408.                 }
  3409.  
  3410.                 SetMask(RPort,DepthMask);
  3411.  
  3412.                 UpdatePens();
  3413.  
  3414.                 ConFontScaleUpdate();
  3415.  
  3416.                 DrawCursor();
  3417.  
  3418.                 ReleaseSemaphore(&TerminalSemaphore);
  3419.             }
  3420.  
  3421.             break;
  3422.  
  3423.             /* Reset the whole terminal. */
  3424.  
  3425.         case MEN_RESET_TERMINAL:
  3426.  
  3427.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3428.                 XEmulatorResetConsole(XEM_IO);
  3429.             else
  3430.             {
  3431.                 FreeMarker();
  3432.  
  3433.                 ConBypass("\033c",-1);
  3434.             }
  3435.  
  3436.             break;
  3437.  
  3438.         case MEN_SET_EMULATION:
  3439.  
  3440.             BlockWindows();
  3441.  
  3442.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3443.             {
  3444.                 OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  3445.  
  3446.                 NewOptions = FALSE;
  3447.  
  3448.                 XEmulatorOptions(XEM_IO);
  3449.  
  3450.                 if(NewOptions)
  3451.                 {
  3452.                     SetEmulatorOptions(XEM_PREFS_SAVE);
  3453.  
  3454.                     NewOptions = FALSE;
  3455.                 }
  3456.  
  3457.                 OptionTitle = NULL;
  3458.             }
  3459.             else
  3460.             {
  3461.                 if(EmulationPanel(Config,NULL))
  3462.                 {
  3463.                     ConfigSetup();
  3464.  
  3465.                     ConfigChanged = TRUE;
  3466.                 }
  3467.             }
  3468.  
  3469.             ReleaseWindows();
  3470.  
  3471.             break;
  3472.  
  3473.             /* Set the serial preferences. */
  3474.  
  3475.         case MEN_SERIAL:
  3476.  
  3477.             BlockWindows();
  3478.  
  3479.             if(SerialPanel(Config,NULL))
  3480.             {
  3481.                 ConfigSetup();
  3482.  
  3483.                 ConfigChanged = TRUE;
  3484.             }
  3485.  
  3486.             ReleaseWindows();
  3487.  
  3488.             break;
  3489.  
  3490.             /* Set the modem preferences. */
  3491.  
  3492.         case MEN_MODEM:
  3493.  
  3494.             BlockWindows();
  3495.  
  3496.             if(ModemPanel(Config,NULL))
  3497.             {
  3498.                 FlowInit(TRUE);
  3499.  
  3500.                 ConfigChanged = TRUE;
  3501.             }
  3502.  
  3503.             ReleaseWindows();
  3504.  
  3505.             break;
  3506.  
  3507.             /* Set the screen preferences. */
  3508.  
  3509.         case MEN_SCREEN:
  3510.  
  3511.             BlockWindows();
  3512.  
  3513.             if(ScreenPanel(Config,NULL))
  3514.             {
  3515.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3516.                 {
  3517.                     switch(Config -> ScreenConfig -> ColourMode)
  3518.                     {
  3519.                         case COLOUR_EIGHT:
  3520.  
  3521.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3522.                             break;
  3523.  
  3524.                         case COLOUR_SIXTEEN:
  3525.  
  3526.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3527.                             break;
  3528.  
  3529.                         case COLOUR_AMIGA:
  3530.  
  3531.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3532.                             break;
  3533.  
  3534.                         case COLOUR_MONO:
  3535.  
  3536.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3537.                             break;
  3538.                     }
  3539.                 }
  3540.  
  3541.                 ConfigSetup();
  3542.  
  3543.                 ConfigChanged = TRUE;
  3544.             }
  3545.             else
  3546.             {
  3547.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3548.                 {
  3549.                     switch(Config -> ScreenConfig -> ColourMode)
  3550.                     {
  3551.                         case COLOUR_EIGHT:
  3552.  
  3553.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3554.                             break;
  3555.  
  3556.                         case COLOUR_SIXTEEN:
  3557.  
  3558.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3559.                             break;
  3560.  
  3561.                         case COLOUR_AMIGA:
  3562.  
  3563.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3564.                             break;
  3565.  
  3566.                         case COLOUR_MONO:
  3567.  
  3568.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3569.                             break;
  3570.                     }
  3571.  
  3572.                     ConfigChanged = TRUE;
  3573.                 }
  3574.             }
  3575.  
  3576.             ReleaseWindows();
  3577.  
  3578.             break;
  3579.  
  3580.             /* Set the terminal preferences. */
  3581.  
  3582.         case MEN_TERMINAL:
  3583.  
  3584.             BlockWindows();
  3585.  
  3586.             if(TerminalPanel(Config,NULL))
  3587.             {
  3588.                 Update_CR_LF_Translation();
  3589.  
  3590.                 ConfigSetup();
  3591.  
  3592.                 ConfigChanged = TRUE;
  3593.             }
  3594.  
  3595.             ReleaseWindows();
  3596.  
  3597.             break;
  3598.  
  3599.             /* Set the clipboard preferences. */
  3600.  
  3601.         case MEN_CLIPBOARD:
  3602.  
  3603.             BlockWindows();
  3604.  
  3605.             if(ClipPanel(Config,NULL))
  3606.             {
  3607.                 ConfigSetup();
  3608.  
  3609.                 ConfigChanged = TRUE;
  3610.             }
  3611.  
  3612.             ReleaseWindows();
  3613.  
  3614.             break;
  3615.  
  3616.             /* Set the capture preferences. */
  3617.  
  3618.         case MEN_CAPTURE:
  3619.  
  3620.             BlockWindows();
  3621.  
  3622.             if(CapturePanel(Config,NULL))
  3623.             {
  3624.                 ConOutputUpdate();
  3625.  
  3626.                 ConfigSetup();
  3627.  
  3628.                 ConfigChanged = TRUE;
  3629.             }
  3630.  
  3631.             ReleaseWindows();
  3632.  
  3633.             break;
  3634.  
  3635.             /* Set the command preferences. */
  3636.  
  3637.         case MEN_COMMANDS:
  3638.  
  3639.             BlockWindows();
  3640.  
  3641.             if(CommandPanel(Config,NULL))
  3642.                 ConfigChanged = TRUE;
  3643.  
  3644.             ReleaseWindows();
  3645.  
  3646.             break;
  3647.  
  3648.             /* Set the miscellaneous preferences. */
  3649.  
  3650.         case MEN_MISC:
  3651.  
  3652.             BlockWindows();
  3653.  
  3654.             if(MiscPanel(Config,NULL))
  3655.             {
  3656.                 ConfigSetup();
  3657.  
  3658.                 ConfigChanged = TRUE;
  3659.             }
  3660.  
  3661.             ReleaseWindows();
  3662.  
  3663.             break;
  3664.  
  3665.             /* Set the path settings. */
  3666.  
  3667.         case MEN_PATH:
  3668.  
  3669.             BlockWindows();
  3670.  
  3671.             if(PathPanel(Config,NULL))
  3672.                 ConfigChanged = TRUE;
  3673.  
  3674.             ReleaseWindows();
  3675.  
  3676.             break;
  3677.  
  3678.             /* Set the file transfer options. */
  3679.  
  3680.         case MEN_TRANSFER:
  3681.  
  3682.             BlockWindows();
  3683.  
  3684.             XprIO -> xpr_filename = NULL;
  3685.  
  3686.                 /* Set up the library options. */
  3687.  
  3688.             if(XProtocolBase)
  3689.             {
  3690.                 XPRCommandSelected = FALSE;
  3691.  
  3692.                 ClearSerial();
  3693.  
  3694.                 NewOptions = FALSE;
  3695.  
  3696.                 TransferBits = XProtocolSetup(XprIO);
  3697.  
  3698.                 RestartSerial(FALSE);
  3699.  
  3700.                 DeleteTransferPanel(TRUE);
  3701.  
  3702.                     /* Successful? */
  3703.  
  3704. /*                if(!XPRCommandSelected)*/
  3705.                 {
  3706.                     if(!(TransferBits & XPRS_SUCCESS))
  3707.                     {
  3708.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  3709.  
  3710.                         CloseLibrary(XProtocolBase);
  3711.  
  3712.                         XProtocolBase = NULL;
  3713.  
  3714.                         LastXprLibrary[0] = 0;
  3715.  
  3716.                         TransferBits = 0;
  3717.  
  3718.                         SetTransferMenu(FALSE);
  3719.                     }
  3720.                     else
  3721.                         SaveProtocolOpts();
  3722.                 }
  3723.             }
  3724.  
  3725.             ReleaseWindows();
  3726.  
  3727.             break;
  3728.  
  3729.             /* Set the file transfer procol settings. */
  3730.  
  3731.         case MEN_TRANSFER_PROTOCOL:
  3732.  
  3733.             BlockWindows();
  3734.  
  3735.             if(LibPanel(Config,NULL))
  3736.             {
  3737.                 ConfigSetup();
  3738.  
  3739.                 ConfigChanged = TRUE;
  3740.  
  3741.                 FlowInit(TRUE);
  3742.             }
  3743.  
  3744.             ReleaseWindows();
  3745.  
  3746.             break;
  3747.  
  3748.             /* Set the translation tables. */
  3749.  
  3750.         case MEN_TRANSLATION:
  3751.  
  3752.             BlockWindows();
  3753.  
  3754.             TranslationChanged |= TranslationPanel(&SendTable,&ReceiveTable,LastTranslation,Window);
  3755.  
  3756.                 /* Choose the right console write routine. */
  3757.  
  3758.             ConOutputUpdate();
  3759.  
  3760.             ReleaseWindows();
  3761.  
  3762.             break;
  3763.  
  3764.             /* Set the keyboard macros. */
  3765.  
  3766.         case MEN_MACROS:
  3767.  
  3768.             BlockWindows();
  3769.  
  3770.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3771.             {
  3772.                 XEmulatorMacroKeyFilter(XEM_IO,NULL);
  3773.  
  3774.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window);
  3775.  
  3776.                 SetupXEM_MacroKeys(MacroKeys);
  3777.             }
  3778.             else
  3779.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window);
  3780.  
  3781.             ReleaseWindows();
  3782.  
  3783.             break;
  3784.  
  3785.             /* Set the cursor keys. */
  3786.  
  3787.         case MEN_CURSORKEYS:
  3788.  
  3789.             BlockWindows();
  3790.  
  3791.             CursorKeysChanged |= CursorPanel(CursorKeys,LastCursorKeys,Window);
  3792.  
  3793.             ReleaseWindows();
  3794.  
  3795.             break;
  3796.  
  3797.             /* Set the fast macros. */
  3798.  
  3799.         case MEN_FAST_MACROS:
  3800.  
  3801.             BlockWindows();
  3802.  
  3803.                 // Looks weird, doesn't it?  Actually, it's quite harmless. If FastMacroPanel()
  3804.                 // returns TRUE, FastMacrosChanged won't be modified. If FastMacrosChanged is
  3805.                 // modified, it will always be set to FALSE and FastMacroPanel() will also return
  3806.                 // FALSE.
  3807.  
  3808.             FastMacrosChanged |= FastMacroPanel(&FastMacroList,LastFastMacros,Window,&FastMacrosChanged);
  3809.  
  3810.             ReleaseWindows();
  3811.  
  3812.             break;
  3813.  
  3814.             /* Set the hotkey preferences. */
  3815.  
  3816.         case MEN_HOTKEYS:
  3817.  
  3818.             BlockWindows();
  3819.  
  3820.             if(HotkeyPanel(&Hotkeys))
  3821.             {
  3822.                 if(!SetupCx())
  3823.                     MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3824.             }
  3825.  
  3826.             ReleaseWindows();
  3827.  
  3828.             break;
  3829.  
  3830.             /* Set the speech preferences. */
  3831.  
  3832.         case MEN_SPEECH:
  3833.  
  3834.             BlockWindows();
  3835.  
  3836.             SpeechPanel();
  3837.  
  3838.             ReleaseWindows();
  3839.  
  3840.             break;
  3841.  
  3842.             /* Set the sound preferences. */
  3843.  
  3844.         case MEN_SOUND:
  3845.  
  3846.             BlockWindows();
  3847.  
  3848.             if(SoundPanel(&SoundConfig))
  3849.                 SoundInit();
  3850.  
  3851.             ReleaseWindows();
  3852.  
  3853.             break;
  3854.  
  3855.             /* Edit the phone number patterns and rates. */
  3856.  
  3857.             /* Edit the trap settings? */
  3858.  
  3859.         case MEN_RATES:
  3860.  
  3861.             BlockWindows();
  3862.  
  3863.             PatternPanel();
  3864.  
  3865.             ReleaseWindows();
  3866.  
  3867.             break;
  3868.  
  3869.             /* Open the preferences settings. */
  3870.  
  3871.         case MEN_OPEN_SETTINGS:
  3872.  
  3873.             BlockWindows();
  3874.  
  3875.             strcpy(DummyBuffer,LastConfig);
  3876.  
  3877.             DummyChar = PathPart(DummyBuffer);
  3878.  
  3879.             *DummyChar = 0;
  3880.  
  3881.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL,TRUE))
  3882.             {
  3883.                 if(ReadConfig(DummyBuffer,PrivateConfig))
  3884.                 {
  3885.                     SwapConfig(PrivateConfig,Config);
  3886.  
  3887.                     strcpy(LastConfig,DummyBuffer);
  3888.  
  3889.                     ConfigSetup();
  3890.  
  3891.                     ConfigChanged = FALSE;
  3892.                 }
  3893.                 else
  3894.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  3895.  
  3896.                 FreeAslRequest(FileRequest);
  3897.             }
  3898.  
  3899.             ReleaseWindows();
  3900.  
  3901.             break;
  3902.  
  3903.             /* Save the terminal preferences. */
  3904.  
  3905.         case MEN_SAVE_SETTINGS:
  3906.  
  3907.             if(LastConfig[0])
  3908.             {
  3909.                 BlockWindows();
  3910.  
  3911.                 if(!Screen)
  3912.                     PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
  3913.  
  3914.                 if(!WriteConfig(LastConfig,Config))
  3915.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
  3916.                 else
  3917.                     ConfigChanged = FALSE;
  3918.  
  3919.                 ReleaseWindows();
  3920.  
  3921.                 break;
  3922.             }
  3923.  
  3924.             /* Save the terminal preferences to a
  3925.              * given file name.
  3926.              */
  3927.  
  3928.         case MEN_SAVE_SETTINGS_AS:
  3929.  
  3930.             BlockWindows();
  3931.  
  3932.             strcpy(DummyBuffer,LastConfig);
  3933.  
  3934.             DummyChar = PathPart(DummyBuffer);
  3935.  
  3936.             *DummyChar = 0;
  3937.  
  3938.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL,TRUE))
  3939.             {
  3940.                 if(!Screen)
  3941.                     PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
  3942.  
  3943.                 if(WriteConfig(DummyBuffer,Config))
  3944.                 {
  3945.                     strcpy(LastConfig,DummyBuffer);
  3946.  
  3947.                     ConfigChanged = FALSE;
  3948.                 }
  3949.                 else
  3950.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3951.  
  3952.                 FreeAslRequest(FileRequest);
  3953.             }
  3954.  
  3955.             ReleaseWindows();
  3956.  
  3957.             break;
  3958.  
  3959.             /* Show terminal information window. */
  3960.  
  3961.         case MEN_STATUS_WINDOW:
  3962.  
  3963.             if(InfoWindow)
  3964.                 CloseInfoWindow();
  3965.             else
  3966.                 OpenInfoWindow();
  3967.  
  3968.             break;
  3969.  
  3970.         case MEN_REVIEW_WINDOW:
  3971.  
  3972.             if(ReviewWindow)
  3973.                 DeleteReview();
  3974.             else
  3975.                 CreateReview();
  3976.  
  3977.             break;
  3978.  
  3979.             /* Open the packet window if necessary, else
  3980.              * just activate it.
  3981.              */
  3982.  
  3983.         case MEN_PACKET_WINDOW:
  3984.  
  3985.             CreatePacketWindow();
  3986.             break;
  3987.  
  3988.             // Enable or disable the packet window
  3989.  
  3990.         case MEN_CHAT_LINE:
  3991.  
  3992.             if(Item = FindThisItem(Menu,MEN_CHAT_LINE))
  3993.             {
  3994.                 BOOL NewState;
  3995.  
  3996.                 if(Item -> Flags & CHECKED)
  3997.                     NewState = TRUE;
  3998.                 else
  3999.                     NewState = FALSE;
  4000.  
  4001.                 if(ChatMode != NewState)
  4002.                 {
  4003.                     ChatMode = NewState;
  4004.  
  4005.                     ResetDisplay = TRUE;
  4006.                 }
  4007.             }
  4008.  
  4009.             break;
  4010.  
  4011.             /* Toggle the presence of the fast! macro panel. */
  4012.  
  4013.         case MEN_FAST_MACROS_WINDOW:
  4014.  
  4015.             if(FastWindow)
  4016.                 CloseFastWindow();
  4017.             else
  4018.                 OpenFastWindow();
  4019.  
  4020.             break;
  4021.  
  4022.             /* Open the upload queue window. */
  4023.  
  4024.         case MEN_UPLOAD_QUEUE_WINDOW:
  4025.  
  4026.             CreateQueueProcess();
  4027.             break;
  4028.  
  4029.         default:if(Code >= DIAL_MENU_LIMIT)
  4030.             {
  4031.                 LONG Index = Code - DIAL_MENU_LIMIT;
  4032.  
  4033.                 ObtainSemaphore(&OnlineSemaphore);
  4034.  
  4035.                 if(!LocalDialList && (!Online || Config -> MiscConfig -> ProtectiveMode))
  4036.                 {
  4037.                     ReleaseSemaphore(&OnlineSemaphore);
  4038.  
  4039.                     if(LocalDialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
  4040.                     {
  4041.                         LONG i;
  4042.  
  4043.                             /* Clear previous list contents, we
  4044.                              * don't want to redial yet.
  4045.                              */
  4046.  
  4047.                         for(i = 0 ; i < NumPhoneEntries ; i++)
  4048.                             Phonebook[i] -> Count = -1;
  4049.  
  4050.                         NewList(LocalDialList);
  4051.                     }
  4052.                 }
  4053.                 else
  4054.                     ReleaseSemaphore(&OnlineSemaphore);
  4055.  
  4056.                 if(Phonebook[Index] -> Count == -1)
  4057.                 {
  4058.                     if(LocalDialList)
  4059.                     {
  4060.                         struct PhoneNode *NewNode;
  4061.  
  4062.                             /* Create a new node to be added to the dial list. */
  4063.  
  4064.                         if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
  4065.                         {
  4066.                                 /* Take care of the name and the corresponding phone book entry. */
  4067.  
  4068.                             NewNode -> VanillaNode . ln_Name    = NewNode -> LocalName;
  4069.                             NewNode -> Entry            = Phonebook[Index];
  4070.  
  4071.                             Phonebook[Index] -> Count = ++LocalCount;
  4072.  
  4073.                             SPrintf(NewNode -> LocalName,"%3ld - %s",LocalCount + 1,Phonebook[Index] -> Header -> Name);
  4074.  
  4075.                                 /* Install back-link. */
  4076.  
  4077.                             NewNode -> Entry -> Node = NewNode;
  4078.  
  4079.                             AddTail(LocalDialList,&NewNode -> VanillaNode);
  4080.                         }
  4081.                     }
  4082.                 }
  4083.             }
  4084.  
  4085.             break;
  4086.     }
  4087. }
  4088.  
  4089.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  4090.      *
  4091.      *    Skip along the number of selected menu items and
  4092.      *    handle the associated functions.
  4093.      */
  4094.  
  4095. VOID __regargs
  4096. HandleMenu(ULONG Code,ULONG Qualifier)
  4097. {
  4098.     struct MenuItem *MenuItem;
  4099.  
  4100.     DisplayReopened = FALSE;
  4101.  
  4102.         /* Check until the last menuitem has been
  4103.          * processed.
  4104.          */
  4105.  
  4106.     while(Code != MENUNULL)
  4107.     {
  4108.             /* Pick up the associated menu item. */
  4109.  
  4110.         if(MenuItem = ItemAddress(Menu,Code))
  4111.         {
  4112.             HandleMenuCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
  4113.  
  4114.             if(Apocalypse)
  4115.                 return;
  4116.  
  4117.             if(DisplayReopened)
  4118.             {
  4119.                 DisplayReopened = FALSE;
  4120.  
  4121.                 return;
  4122.             }
  4123.  
  4124.             Code = MenuItem -> NextSelect;
  4125.         }
  4126.         else
  4127.             break;
  4128.     }
  4129.  
  4130.         /* If the modem is still online, provide help. */
  4131.  
  4132.     if(LocalDialList)
  4133.     {
  4134.         if(!AskDial(Window))
  4135.         {
  4136.             FreeList(LocalDialList);
  4137.  
  4138.             FreeVecPooled(LocalDialList);
  4139.  
  4140.             LocalDialList = NULL;
  4141.  
  4142.             LocalCount = -1;
  4143.         }
  4144.     }
  4145.  
  4146.     HandleLocalDialList(FALSE);
  4147. }
  4148.  
  4149.     /* HandleWorkbenchWindow():
  4150.      *
  4151.      *    Handle input coming from the Workbench window.
  4152.      */
  4153.  
  4154. BYTE
  4155. HandleWorkbenchWindow()
  4156. {
  4157.     struct FileInfoBlock    *FileInfo;
  4158.     struct AppMessage    *AppMessage;
  4159.  
  4160.     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4161.     {
  4162.         struct FileTransferInfo *Info;
  4163.  
  4164.         if(Info = AllocFileTransferInfo())
  4165.         {
  4166.             LONG FilesFound = 0,i;
  4167.             BYTE Success = TRUE;
  4168.  
  4169.             while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  4170.             {
  4171.                 if(Success && AppMessage -> am_Type == MTYPE_APPWINDOW)
  4172.                 {
  4173.                     for(i = 0 ; Success && i < AppMessage -> am_NumArgs ; i++)
  4174.                     {
  4175.                         if(AppMessage -> am_ArgList[i] . wa_Lock && AppMessage -> am_ArgList[i] . wa_Name)
  4176.                         {
  4177.                             BPTR OldLock;
  4178.  
  4179.                             if(OldLock = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock))
  4180.                             {
  4181.                                 BPTR FileLock;
  4182.  
  4183.                                 if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
  4184.                                 {
  4185.                                     if(Examine(FileLock,FileInfo))
  4186.                                     {
  4187.                                         if(FileInfo -> fib_DirEntryType < 0)
  4188.                                         {
  4189.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  4190.                                             {
  4191.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4192.                                                     Success = FALSE;
  4193.                                                 else
  4194.                                                 {
  4195.                                                     FilesFound++;
  4196.  
  4197.                                                     if(Config -> TransferConfig -> TransferIcons)
  4198.                                                     {
  4199.                                                         BPTR InfoLock;
  4200.  
  4201.                                                         strcat(SharedBuffer,".info");
  4202.  
  4203.                                                         if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  4204.                                                         {
  4205.                                                             if(Examine(InfoLock,FileInfo))
  4206.                                                             {
  4207.                                                                 if(FileInfo -> fib_DirEntryType < 0)
  4208.                                                                 {
  4209.                                                                     if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4210.                                                                         Success = FALSE;
  4211.                                                                     else
  4212.                                                                         FilesFound++;
  4213.                                                                 }
  4214.                                                             }
  4215.  
  4216.                                                             UnLock(InfoLock);
  4217.                                                         }
  4218.                                                     }
  4219.                                                 }
  4220.                                             }
  4221.                                         }
  4222.                                     }
  4223.  
  4224.                                     UnLock(FileLock);
  4225.                                 }
  4226.  
  4227.                                 CurrentDir(OldLock);
  4228.                             }
  4229.                         }
  4230.                     }
  4231.                 }
  4232.  
  4233.                 ReplyMsg((struct Message *)AppMessage);
  4234.             }
  4235.  
  4236.             if(FilesFound)
  4237.             {
  4238.                 SortFileTransferInfo(Info);
  4239.  
  4240.                 BlockWindows();
  4241.  
  4242.                 switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILES_AS_TXT),LocaleString(MSG_TERMMAIN_BINARY_UPLOAD_CANCEL_TXT)))
  4243.                 {
  4244.                     case 1:    BinaryTransfer        = TRUE;
  4245.                         FileTransferInfo    = Info;
  4246.  
  4247.                         StartXprSendFromList(TRANSFER_BINARY,TRUE);
  4248.  
  4249.                         break;
  4250.  
  4251.                     case 2:    BinaryTransfer        = FALSE;
  4252.                         FileTransferInfo    = Info;
  4253.  
  4254.                         StartXprSendFromList(TRANSFER_TEXT,TRUE);
  4255.  
  4256.                         break;
  4257.  
  4258.                     case 0:    FreeFileTransferInfo(Info);
  4259.                         break;
  4260.                 }
  4261.  
  4262.                 ReleaseWindows();
  4263.             }
  4264.         }
  4265.  
  4266.         FreeDosObject(DOS_FIB,FileInfo);
  4267.     }
  4268.  
  4269.     while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  4270.         ReplyMsg((struct Message *)AppMessage);
  4271.  
  4272.     return(FALSE);
  4273. }
  4274.  
  4275.     /* HandleIconify():
  4276.      *
  4277.      *    Handle program iconification.
  4278.      */
  4279.  
  4280. VOID
  4281. HandleIconify()
  4282. {
  4283.     BYTE Released = FALSE;
  4284.  
  4285.         /* Set the wait mouse pointer... */
  4286.  
  4287.     BlockWindows();
  4288.  
  4289.         /* Open workbench.library. */
  4290.  
  4291.     if(WorkbenchBase)
  4292.     {
  4293.             /* Open icon.library. */
  4294.  
  4295.         if(IconBase)
  4296.         {
  4297.             struct DiskObject    *Icon = NULL;
  4298.             UBYTE             LocalBuffer[MAX_FILENAME_LENGTH];
  4299.  
  4300.             strcpy(LocalBuffer,Config -> PathConfig -> DefaultStorage);
  4301.  
  4302.             if(AddPart(LocalBuffer,"term_SleepIcon",MAX_FILENAME_LENGTH))
  4303.                 Icon = GetDiskObject(LocalBuffer);
  4304.  
  4305.             if(!Icon)
  4306.                 Icon = GetDiskObject("PROGDIR:term_SleepIcon");
  4307.  
  4308.             if(!Icon)
  4309.             {
  4310.                 if(!(Icon = GetProgramIcon()))
  4311.                     Icon = GetDefDiskObject(WBTOOL);
  4312.             }
  4313.  
  4314.                 /* Did we get an icon? */
  4315.  
  4316.             if(Icon)
  4317.             {
  4318.                 struct MsgPort *IconPort;
  4319.  
  4320.                     /* Reset the icon type. */
  4321.  
  4322.                 Icon -> do_Type        = NULL;
  4323.  
  4324.                     /* Default icon position. */
  4325.  
  4326.                 Icon -> do_CurrentX    = NO_ICON_POSITION;
  4327.                 Icon -> do_CurrentY    = NO_ICON_POSITION;
  4328.  
  4329.                     /* Create the Workbench reply port. */
  4330.  
  4331.                 if(IconPort = CreateMsgPort())
  4332.                 {
  4333.                     struct AppIcon *AppIcon;
  4334.  
  4335.                         /* Add the application icon. */
  4336.  
  4337.                     if(AppIcon = AddAppIconA(0,0,TermIDString,IconPort,NULL,Icon,NULL))
  4338.                     {
  4339.                         struct AppMessage    *AppMessage;
  4340.                         UBYTE            *String,*Error;
  4341.                         ULONG             SignalSet;
  4342.  
  4343.                             /* Reset the guardian. */
  4344.  
  4345.                         IconTerminated = FALSE;
  4346.  
  4347.                             /* Release the window. */
  4348.  
  4349.                         Released = TRUE;
  4350.  
  4351.                         ReleaseWindows();
  4352.  
  4353.                         WindowBox . Left    = Window -> LeftEdge;
  4354.                         WindowBox . Top        = Window -> TopEdge;
  4355.                         WindowBox . Width    = Window -> Width;
  4356.                         WindowBox . Height    = Window -> Height;
  4357.  
  4358.                             /* Close the display. full stop. */
  4359.  
  4360.                         if(DeleteDisplay())
  4361.                         {
  4362.                                 /* Reset and release the serial driver. */
  4363.  
  4364.                             if(Config -> MiscConfig -> ReleaseDevice)
  4365.                             {
  4366.                                 ClearSerial();
  4367.  
  4368.                                 DeleteSerial();
  4369.                             }
  4370.  
  4371.                                 /* Wait for double-click. */
  4372.  
  4373. IconLoop:                        while(!IconTerminated)
  4374.                             {
  4375.                                 SignalSet = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
  4376.  
  4377.                                 if(SignalSet & PORTMASK(IconPort))
  4378.                                 {
  4379.                                         /* Pick up application messages. */
  4380.  
  4381.                                     while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4382.                                     {
  4383.                                             /* Received a double-click? */
  4384.  
  4385.                                         IconTerminated = TRUE;
  4386.  
  4387.                                         ReplyMsg(AppMessage);
  4388.                                     }
  4389.                                 }
  4390.  
  4391.                                     /* Wake up if ARexx command received. */
  4392.  
  4393.                                 if(SignalSet & SIG_REXX)
  4394.                                     while(HandleRexx());
  4395.  
  4396.                                 if(SignalSet & SIGBREAKF_CTRL_F)
  4397.                                     IconTerminated = TRUE;
  4398.                             }
  4399.  
  4400.                                 /* Open the serial driver. */
  4401.  
  4402.                             if(Config -> MiscConfig -> ReleaseDevice)
  4403.                             {
  4404.                                 if(Error = CreateSerial())
  4405.                                 {
  4406.                                     DeleteSerial();
  4407.  
  4408.                                     switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
  4409.                                     {
  4410.                                         case 1:    IconTerminated = FALSE;
  4411.                                             goto IconLoop;
  4412.  
  4413.                                         case 0:    MainTerminated = TRUE;
  4414.                                     }
  4415.                                 }
  4416.                                 else
  4417.                                 {
  4418.                                     if(SerialMessage)
  4419.                                     {
  4420.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  4421.  
  4422.                                         SerialMessage = NULL;
  4423.                                     }
  4424.                                 }
  4425.                             }
  4426.  
  4427.                             if(CantQuit && MainTerminated)
  4428.                                 MainTerminated = FALSE;
  4429.  
  4430.                                 /* Create the display. */
  4431.  
  4432.                             if(!MainTerminated)
  4433.                             {
  4434.                                 if(String = CreateDisplay(FALSE))
  4435.                                 {
  4436.                                     if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  4437.                                     {
  4438.                                         ClearSerial();
  4439.  
  4440.                                         DeleteSerial();
  4441.  
  4442.                                         IconTerminated = FALSE;
  4443.  
  4444.                                         goto IconLoop;
  4445.                                     }
  4446.                                     else
  4447.                                         MainTerminated = TRUE;
  4448.                                 }
  4449.                                 else
  4450.                                 {
  4451.                                     BumpWindow(Window);
  4452.  
  4453.                                     PubScreenStuff();
  4454.                                 }
  4455.                             }
  4456.                         }
  4457.                         else
  4458.                         {
  4459.                             BlockWindows();
  4460.  
  4461.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  4462.  
  4463.                             ReleaseWindows();
  4464.                         }
  4465.  
  4466.                             /* Remove the application icon. */
  4467.  
  4468.                         RemoveAppIcon(AppIcon);
  4469.  
  4470.                             /* Reply pending messages. */
  4471.  
  4472.                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4473.                             ReplyMsg(AppMessage);
  4474.                     }
  4475.                     else
  4476.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4477.  
  4478.                     DeleteMsgPort(IconPort);
  4479.                 }
  4480.                 else
  4481.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4482.  
  4483.                 FreeDiskObject(Icon);
  4484.             }
  4485.             else
  4486.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4487.         }
  4488.         else
  4489.             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4490.     }
  4491.     else
  4492.         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4493.  
  4494.     if(!Released)
  4495.         ReleaseWindows();
  4496.  
  4497.         /* Finished! */
  4498.  
  4499.     DoIconify = FALSE;
  4500. }
  4501.  
  4502.     /* HandleOnlineCleanup():
  4503.      *
  4504.      *    Perform offline cleanup tasks.
  4505.      */
  4506.  
  4507. VOID __regargs
  4508. HandleOnlineCleanup(BOOL Hangup)
  4509. {
  4510.     SoundPlay(SOUND_DISCONNECT);
  4511.  
  4512.         /* Execute logoff macro. */
  4513.  
  4514.     if(Config -> CommandConfig -> LogoffMacro[0] && WasOnline)
  4515.         SerialCommand(Config -> CommandConfig -> LogoffMacro);
  4516.  
  4517.     StopCall(FALSE);
  4518.  
  4519.     if(CurrentPay)
  4520.     {
  4521.         if(Hangup)
  4522.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT),CreateSum(CurrentPay,TRUE));
  4523.         else
  4524.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_COST_TXT),CreateSum(CurrentPay,TRUE));
  4525.     }
  4526.     else
  4527.     {
  4528.         if(Hangup)
  4529.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  4530.         else
  4531.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4532.     }
  4533.  
  4534.     SetDialMenu(TRUE);
  4535.  
  4536.     if(!Hangup)
  4537.         Say(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4538.  
  4539.         /* Clear the password. */
  4540.  
  4541.     Password[0]        = 0;
  4542.     UserName[0]        = 0;
  4543.  
  4544.     CurrentBBSName[0]    = 0;
  4545.     CurrentBBSComment[0]    = 0;
  4546.     CurrentBBSNumber[0]    = 0;
  4547.  
  4548.     ObtainSemaphore(&OnlineSemaphore);
  4549.  
  4550.     if(!Config -> SerialConfig -> CheckCarrier || Config -> SerialConfig -> DirectConnection)
  4551.         Online = WasOnline = FALSE;
  4552.  
  4553.     ReleaseSemaphore(&OnlineSemaphore);
  4554.  
  4555.     ObtainSemaphore(&PatternSemaphore);
  4556.  
  4557.     ChosenEntry    = NULL;
  4558.     ChosenPattern    = NULL;
  4559.  
  4560.     ReleaseSemaphore(&PatternSemaphore);
  4561.  
  4562.     LimitCount = -1;
  4563.  
  4564.         /* Previous configuration available? */
  4565.  
  4566.     if(BackupConfig)
  4567.     {
  4568.             /* Remember old configuration. */
  4569.  
  4570.         SaveConfig(Config,PrivateConfig);
  4571.  
  4572.             /* Copy configuration. */
  4573.  
  4574.         SaveConfig(BackupConfig,Config);
  4575.  
  4576.             /* Set up new configuration. */
  4577.  
  4578.         ConfigSetup();
  4579.  
  4580.             /* Free old configuration. */
  4581.  
  4582.         DeleteConfiguration(BackupConfig);
  4583.  
  4584.         BackupConfig = NULL;
  4585.     }
  4586.  
  4587.     if(!ResetDisplay && CurrentPay)
  4588.     {
  4589.             /* Reset the text rendering styles, font, etc. in
  4590.              * order to keep the following text from getting
  4591.              * illegible.
  4592.              */
  4593.  
  4594.         SoftReset();
  4595.  
  4596.             /* Display how much we expect
  4597.              * the user will have to pay for
  4598.              * this call.
  4599.              */
  4600.  
  4601.         ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  4602.  
  4603.         CurrentPay = 0;
  4604.     }
  4605.  
  4606.     if(Config -> ModemConfig -> RedialAfterHangup)
  4607.     {
  4608.         if(DialList)
  4609.         {
  4610.             if(DialList -> lh_Head -> ln_Succ)
  4611.             {
  4612.                 ObtainSemaphore(&OnlineSemaphore);
  4613.  
  4614.                 Online = WasOnline = FALSE;
  4615.  
  4616.                 ReleaseSemaphore(&OnlineSemaphore);
  4617.  
  4618.                 DoDial = DIAL_REDIAL;
  4619.             }
  4620.         }
  4621.     }
  4622. }
  4623.  
  4624.     /* HandleFlowChange():
  4625.      *
  4626.      *    Handle data flow scanner information.
  4627.      */
  4628.  
  4629. VOID
  4630. HandleFlowChange()
  4631. {
  4632.     ObtainSemaphore(&OnlineSemaphore);
  4633.  
  4634.     if(Online)
  4635.     {
  4636.         if(FlowInfo . NoCarrier)
  4637.         {
  4638.             if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
  4639.             {
  4640.                     /* Is the carrier still present? */
  4641.  
  4642.                 if(!(GetSerialStatus() & CIAF_COMCD))    // = Carrier detected
  4643.                     FlowInfo . NoCarrier = FALSE;
  4644.             }
  4645.  
  4646.             if(FlowInfo . NoCarrier)
  4647.             {
  4648.                 if(Online)
  4649.                 {
  4650.                     WasOnline    = Online;
  4651.                     Online        = FALSE;
  4652.                 }
  4653.             }
  4654.         }
  4655.  
  4656.         ReleaseSemaphore(&OnlineSemaphore);
  4657.     }
  4658.     else
  4659.     {
  4660.         ReleaseSemaphore(&OnlineSemaphore);
  4661.  
  4662.         if(FlowInfo . Voice)
  4663.         {
  4664.             UBYTE DateTimeBuffer[256];
  4665.  
  4666.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4667.  
  4668.             WakeUp(Window,SOUND_VOICE);
  4669.  
  4670.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
  4671.  
  4672.             Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  4673.         }
  4674.  
  4675.         if(FlowInfo . Ring)
  4676.         {
  4677.             UBYTE DateTimeBuffer[256];
  4678.  
  4679.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4680.  
  4681.             WakeUp(Window,SOUND_RING);
  4682.  
  4683.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
  4684.  
  4685.             Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  4686.         }
  4687.  
  4688.         if(FlowInfo . Connect)
  4689.         {
  4690.                 /* Are we to check the carrier signal? */
  4691.  
  4692.             if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
  4693.             {
  4694.                     /* No carrier signal present? */
  4695.  
  4696.                 if(GetSerialStatus() & CIAF_COMCD)    // = Carrier lost
  4697.                     FlowInfo . Connect = FALSE;
  4698.             }
  4699.  
  4700.             if(FlowInfo . Connect)
  4701.             {
  4702.                 WakeUp(Window,SOUND_CONNECT);
  4703.  
  4704.                 ObtainSemaphore(&OnlineSemaphore);
  4705.  
  4706.                 if(!Online)
  4707.                 {
  4708.                     WasOnline    = Online;
  4709.                     Online        = TRUE;
  4710.                 }
  4711.  
  4712.                 BaudPending = FALSE;
  4713.  
  4714.                 ReleaseSemaphore(&OnlineSemaphore);
  4715.  
  4716.                 SetDialMenu(FALSE);
  4717.             }
  4718.         }
  4719.     }
  4720.  
  4721.         /* Check if we are to prompt the user for
  4722.          * file transfer.
  4723.          */
  4724.  
  4725.     if(FlowInfo . Signature)
  4726.     {
  4727.         WORD Type = FlowInfo . Signature - SCAN_SIGDEFAULTUPLOAD + TRANSFERSIG_DEFAULTUPLOAD;
  4728.  
  4729.         switch(Type)
  4730.         {
  4731.             case TRANSFERSIG_DEFAULTUPLOAD:
  4732.  
  4733.                 BlockWindows();
  4734.  
  4735.                 switch(UploadPanel(TRUE))
  4736.                 {
  4737.                     case UPLOAD_TEXT:
  4738.  
  4739.                         BinaryTransfer = FALSE;
  4740.  
  4741.                         if(!StartXprSend(TRANSFER_TEXT,TRUE))
  4742.                             SerWrite(ZModemCancel,20);
  4743.  
  4744.                         break;
  4745.  
  4746.                     case UPLOAD_BINARY:
  4747.  
  4748.                         BinaryTransfer = TRUE;
  4749.  
  4750.                         if(!StartXprSend(TRANSFER_BINARY,TRUE))
  4751.                             SerWrite(ZModemCancel,20);
  4752.  
  4753.                         break;
  4754.  
  4755.                     case UPLOAD_ABORT:
  4756.  
  4757.                         SerWrite(ZModemCancel,20);
  4758.                         break;
  4759.  
  4760.                     case UPLOAD_BINARY_FROM_LIST:
  4761.  
  4762.                         StartUpload(UPLOAD_BINARY);
  4763.                         break;
  4764.  
  4765.                     case UPLOAD_TEXT_FROM_LIST:
  4766.  
  4767.                         StartUpload(UPLOAD_TEXT);
  4768.                         break;
  4769.                 }
  4770.  
  4771.                 ReleaseWindows();
  4772.  
  4773.                 break;
  4774.  
  4775.             case TRANSFERSIG_DEFAULTDOWNLOAD:
  4776.  
  4777.                 BlockWindows();
  4778.  
  4779.                 switch(UploadPanel(FALSE))
  4780.                 {
  4781.                     case UPLOAD_TEXT:
  4782.  
  4783.                         BinaryTransfer = FALSE;
  4784.  
  4785.                         StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  4786.  
  4787.                         BinaryTransfer = TRUE;
  4788.  
  4789.                         break;
  4790.  
  4791.                     case UPLOAD_BINARY:
  4792.  
  4793.                         BinaryTransfer = TRUE;
  4794.  
  4795.                         StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  4796.  
  4797.                         break;
  4798.                 }
  4799.  
  4800.                 ReleaseWindows();
  4801.  
  4802.                 break;
  4803.  
  4804.             case TRANSFERSIG_ASCIIUPLOAD:
  4805.  
  4806.                 BlockWindows();
  4807.  
  4808.                 if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  4809.                 {
  4810.                     BinaryTransfer = FALSE;
  4811.  
  4812.                     StartXprSend(TRANSFER_ASCII,TRUE);
  4813.  
  4814.                     BinaryTransfer = TRUE;
  4815.                 }
  4816.  
  4817.                 ResetProtocol();
  4818.  
  4819.                 ReleaseWindows();
  4820.  
  4821.                 break;
  4822.  
  4823.             case TRANSFERSIG_ASCIIDOWNLOAD:
  4824.  
  4825.                 BlockWindows();
  4826.  
  4827.                 if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
  4828.                 {
  4829.                     BinaryTransfer = FALSE;
  4830.  
  4831.                     StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  4832.  
  4833.                     BinaryTransfer = TRUE;
  4834.                 }
  4835.  
  4836.                 ResetProtocol();
  4837.  
  4838.                 ReleaseWindows();
  4839.  
  4840.                 break;
  4841.  
  4842.             case TRANSFERSIG_TEXTUPLOAD:
  4843.  
  4844.                 BlockWindows();
  4845.  
  4846.                 if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  4847.                 {
  4848.                     BinaryTransfer = FALSE;
  4849.  
  4850.                     StartXprSend(TRANSFER_TEXT,TRUE);
  4851.  
  4852.                     BinaryTransfer = TRUE;
  4853.                 }
  4854.  
  4855.                 ResetProtocol();
  4856.  
  4857.                 ReleaseWindows();
  4858.  
  4859.                 break;
  4860.  
  4861.             case TRANSFERSIG_TEXTDOWNLOAD:
  4862.  
  4863.                 BlockWindows();
  4864.  
  4865.                 if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
  4866.                 {
  4867.                     BinaryTransfer = FALSE;
  4868.  
  4869.                     StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  4870.  
  4871.                     BinaryTransfer = TRUE;
  4872.                 }
  4873.  
  4874.                 ResetProtocol();
  4875.  
  4876.                 ReleaseWindows();
  4877.  
  4878.                 break;
  4879.  
  4880.  
  4881.             case TRANSFERSIG_BINARYUPLOAD:
  4882.  
  4883.                 BlockWindows();
  4884.  
  4885.                 if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
  4886.                 {
  4887.                     BinaryTransfer = TRUE;
  4888.  
  4889.                     StartXprSend(TRANSFER_BINARY,TRUE);
  4890.                 }
  4891.  
  4892.                 ResetProtocol();
  4893.  
  4894.                 ReleaseWindows();
  4895.  
  4896.                 break;
  4897.  
  4898.             case TRANSFERSIG_BINARYDOWNLOAD:
  4899.  
  4900.                 BlockWindows();
  4901.  
  4902.                 if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
  4903.                 {
  4904.                     BinaryTransfer = TRUE;
  4905.  
  4906.                     StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  4907.                 }
  4908.  
  4909.                 ResetProtocol();
  4910.  
  4911.                 ReleaseWindows();
  4912.  
  4913.                 break;
  4914.         }
  4915.     }
  4916.  
  4917.     FlowInit(TRUE);
  4918. }
  4919.  
  4920.     /* HandleSerialReset():
  4921.      *
  4922.      *    Handle serial device reset.
  4923.      */
  4924.  
  4925. VOID
  4926. HandleSerialReset()
  4927. {
  4928.     ClearSerial();
  4929.  
  4930.     DeleteSerial();
  4931.  
  4932.     BlockWindows();
  4933.  
  4934.     ReopenSerial();
  4935.  
  4936.     ReleaseWindows();
  4937. }
  4938.  
  4939.     /* HandleSerialRelease():
  4940.      *
  4941.      *    Release the serial device driver, then reopen it again.
  4942.      */
  4943.  
  4944. VOID
  4945. HandleSerialRelease()
  4946. {
  4947.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  4948.     BYTE    Continue,SerialClosed;
  4949.  
  4950.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  4951.  
  4952.         /* This might happen if an ARexx user
  4953.          * released the serial device and
  4954.          * failed to reopen it.
  4955.          */
  4956.  
  4957.     if(ReadPort)
  4958.         SerialClosed = FALSE;
  4959.     else
  4960.         SerialClosed = TRUE;
  4961.  
  4962.     BlockWindows();
  4963.  
  4964.         /* Prevent catastrophes! */
  4965.  
  4966.     if(!Config -> MiscConfig -> ProtectiveMode)
  4967.         Continue = TRUE;
  4968.     else
  4969.     {
  4970.         ObtainSemaphore(&OnlineSemaphore);
  4971.  
  4972.         if(Online && !SerialClosed)
  4973.         {
  4974.             ReleaseSemaphore(&OnlineSemaphore);
  4975.  
  4976.             if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  4977.                 Continue = FALSE;
  4978.             else
  4979.                 Continue = TRUE;
  4980.         }
  4981.         else
  4982.         {
  4983.             ReleaseSemaphore(&OnlineSemaphore);
  4984.  
  4985.             Continue = TRUE;
  4986.         }
  4987.     }
  4988.  
  4989.     if(Continue)
  4990.     {
  4991.         if(SerialClosed)
  4992.             ReopenSerial();
  4993.         else
  4994.         {
  4995.             ClearSerial();
  4996.  
  4997.             DeleteSerial();
  4998.  
  4999.             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  5000.                 ReopenSerial();
  5001.             else
  5002.                 MainTerminated = TRUE;
  5003.         }
  5004.     }
  5005.  
  5006.     ReleaseSerial = FALSE;
  5007.  
  5008.     ThisProcess -> pr_WindowPtr = OldPtr;
  5009.  
  5010.     ReleaseWindows();
  5011. }
  5012.  
  5013.     /* HandleExternalEmulation():
  5014.      *
  5015.      *    Handle external emulation event.
  5016.      */
  5017.  
  5018. VOID
  5019. HandleExternalEmulation()
  5020. {
  5021.     if(!XEmulatorSignal(XEM_IO,XEM_Signal))
  5022.     {
  5023.         CloseEmulator();
  5024.  
  5025.         ResetDisplay = TRUE;
  5026.     }
  5027. }
  5028.  
  5029.     /* HandleSerialCheck():
  5030.      *
  5031.      *    Handle routine checkup actions.
  5032.      */
  5033.  
  5034. BYTE
  5035. HandleSerialCheck()
  5036. {
  5037.         // Attempt to lock the serial device?
  5038.  
  5039.     if(PollODU)
  5040.     {
  5041.             // We don't want to poll too often
  5042.  
  5043.         if(PollODUCount++ == 4)
  5044.         {
  5045.             PollODUCount = 0;
  5046.  
  5047.                 // Still supporting the locking protocol?
  5048.  
  5049.             if(Config -> SerialConfig -> UseOwnDevUnit)
  5050.             {
  5051.                     // Allocate the signal
  5052.  
  5053.                 if((OwnDevBit = AllocSignal(-1)) != -1)
  5054.                 {
  5055.                         // Give it a try
  5056.  
  5057.                     if(!AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,OwnDevBit))
  5058.                     {
  5059.                             // Check
  5060.  
  5061.                         ReopenSerial();
  5062.  
  5063.                         PollODU = FALSE;
  5064.                     }
  5065.                     else
  5066.                     {
  5067.                             // No success
  5068.  
  5069.                         FreeSignal(OwnDevBit);
  5070.  
  5071.                         OwnDevBit = -1;
  5072.                     }
  5073.                 }
  5074.             }
  5075.             else
  5076.                 PollODU = FALSE;
  5077.         }
  5078.     }
  5079.  
  5080.         /* Take a look at the carrier signal. */
  5081.  
  5082.     if(Config -> SerialConfig -> CheckCarrier && WriteRequest && !Config -> SerialConfig -> DirectConnection)
  5083.     {
  5084.         register UWORD Status = GetSerialStatus();
  5085.  
  5086.         ObtainSemaphore(&OnlineSemaphore);
  5087.  
  5088.             /* Still online? */
  5089.  
  5090.         if(Online)
  5091.         {
  5092.             ReleaseSemaphore(&OnlineSemaphore);
  5093.  
  5094.                 /* Carrier detect signal lost? */
  5095.  
  5096.             if(Status & CIAF_COMCD)    // = Carrier lost
  5097.             {
  5098.                 ObtainSemaphore(&OnlineSemaphore);
  5099.  
  5100.                 if(Online)
  5101.                 {
  5102.                     WasOnline    = Online;
  5103.                     Online        = FALSE;
  5104.                 }
  5105.  
  5106.                 ReleaseSemaphore(&OnlineSemaphore);
  5107.             }
  5108.         }
  5109.         else
  5110.         {
  5111.             ReleaseSemaphore(&OnlineSemaphore);
  5112.  
  5113.                 /* Is the carrier detect signal
  5114.                  * present?
  5115.                  */
  5116.  
  5117.             if(!(Status & CIAF_COMCD))    // = Carrier detected
  5118.             {
  5119.                 ObtainSemaphore(&OnlineSemaphore);
  5120.  
  5121.                 if(!Online)
  5122.                 {
  5123.                     WasOnline    = Online;
  5124.                     Online        = TRUE;
  5125.                 }
  5126.  
  5127.                 ReleaseSemaphore(&OnlineSemaphore);
  5128.  
  5129.                 BaudCount        = 0;
  5130.                 BaudBuffer[0]        = 0;
  5131.                 BaudPending        = FALSE;
  5132.  
  5133.                 CurrentPay        = 0;
  5134.  
  5135.                 ObtainSemaphore(&PatternSemaphore);
  5136.  
  5137.                 ChosenEntry        = NULL;
  5138.                 ChosenPattern        = NULL;
  5139.  
  5140.                 ReleaseSemaphore(&PatternSemaphore);
  5141.  
  5142.                 Password[0]        = 0;
  5143.                 UserName[0]        = 0;
  5144.  
  5145.                 SendStartup        = FALSE;
  5146.  
  5147.                 LimitCount        = -1;
  5148.  
  5149.                 CurrentBBSName[0]    = 0;
  5150.                 CurrentBBSComment[0]    = 0;
  5151.                 CurrentBBSNumber[0]    = 0;
  5152.  
  5153.                 SetDialMenu(FALSE);
  5154.             }
  5155.         }
  5156.     }
  5157.  
  5158.         /* Check online time limit. */
  5159.  
  5160.     if(!LimitCount)
  5161.     {
  5162.         LimitCount = -1;
  5163.  
  5164.         BlockWindows();
  5165.  
  5166.         SendARexxCommand(LimitMacro,TRUE);
  5167.  
  5168.         ReleaseWindows();
  5169.     }
  5170.  
  5171.         /* Flush capture file contents to disk,
  5172.          * this routine is executed each minute
  5173.          * in order to store the captured data.
  5174.          */
  5175.  
  5176.     if(BufferFlushCount-- <= 0)
  5177.     {
  5178.         BufferFlushCount = 60;
  5179.  
  5180.             /* Flush the capture file. */
  5181.  
  5182.         if(FileCapture)
  5183.             BufferFlush(FileCapture);
  5184.     }
  5185.  
  5186.     return(FALSE);
  5187. }
  5188.  
  5189.     /* HandleQueueMsg():
  5190.      *
  5191.      *    Process the special message queue.
  5192.      */
  5193.  
  5194. BYTE
  5195. HandleQueueMsg()
  5196. {
  5197.     struct DataMsg *Item;
  5198.  
  5199.     if(Item = GetMsgItem(SpecialQueue))
  5200.     {
  5201.         struct FileTransferInfo *Info;
  5202.         BYTE             OldEcho;
  5203.  
  5204.         switch(Item -> Type)
  5205.         {
  5206.                 // Output data.
  5207.  
  5208.             case DATAMSGTYPE_WRITE:
  5209.  
  5210.                 SerWrite(Item -> Data,Item -> Size);
  5211.                 break;
  5212.  
  5213.                 // Execute a command.
  5214.  
  5215.             case DATAMSGTYPE_SERIALCOMMAND:
  5216.  
  5217.                 SerialCommand(Item -> Data);
  5218.                 break;
  5219.  
  5220.                 // Execute a command, but don't echo it.
  5221.  
  5222.             case DATAMSGTYPE_SERIALCOMMANDNOECHO:
  5223.  
  5224.                 OldEcho = Config -> SerialConfig -> Duplex;
  5225.  
  5226.                 Config -> SerialConfig -> Duplex = DUPLEX_FULL;
  5227.  
  5228.                 SerialCommand(Item -> Data);
  5229.  
  5230.                 Config -> SerialConfig -> Duplex = OldEcho;
  5231.                 break;
  5232.  
  5233.                 // Output contents of clipboard
  5234.  
  5235.             case DATAMSGTYPE_WRITECLIP:
  5236.  
  5237.                 if(!ClipInput)
  5238.                 {
  5239.                     if(!OpenClip(Item -> Size))
  5240.                         ClipInput = ClipXerox = TRUE;
  5241.                     else
  5242.                         ClipInput = ClipXerox = FALSE;
  5243.                 }
  5244.  
  5245.                     /* Are we reading input from the clipboard? */
  5246.  
  5247.                 if(ClipInput)
  5248.                 {
  5249.                     UBYTE    InputBuffer[257];
  5250.                     WORD    Len;
  5251.  
  5252.                     if((Len = GetClip(InputBuffer,256,TRUE)) < 0)
  5253.                     {
  5254.                         CloseClip();
  5255.  
  5256.                         ClipInput = FALSE;
  5257.  
  5258.                         if(ClipXerox)
  5259.                         {
  5260.                             if(Config -> ClipConfig -> InsertSuffix[0])
  5261.                                 SerialCommand(Config -> ClipConfig -> InsertSuffix);
  5262.  
  5263.                             ClipXerox = FALSE;
  5264.                         }
  5265.  
  5266.                         ClipPrefix = FALSE;
  5267.                     }
  5268.                     else
  5269.                     {
  5270.                         if(!ClipPrefix && ClipXerox)
  5271.                         {
  5272.                             if(Config -> ClipConfig -> InsertPrefix[0])
  5273.                                 SerialCommand(Config -> ClipConfig -> InsertPrefix);
  5274.  
  5275.                             ClipPrefix = TRUE;
  5276.                         }
  5277.  
  5278.                         if(Len > 0)
  5279.                             SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
  5280.                     }
  5281.                 }
  5282.  
  5283.                 break;
  5284.  
  5285.                 // Start an upload
  5286.  
  5287.             case DATAMSGTYPE_UPLOAD:
  5288.  
  5289.                 if(((struct List *)Item -> Data) -> lh_Head -> ln_Succ)
  5290.                 {
  5291.                     if(Info = AllocFileTransferInfo())
  5292.                     {
  5293.                         struct FileInfoBlock *FileInfo;
  5294.                         LONG FilesFound = 0,Type = Item -> Size;
  5295.  
  5296.                         if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  5297.                         {
  5298.                             BPTR FileLock;
  5299.                             struct List *List;
  5300.                             struct Node *Node,*Next;
  5301.                             APTR OldPtr = ThisProcess -> pr_WindowPtr;
  5302.  
  5303.                             ThisProcess -> pr_WindowPtr = (APTR)-1;
  5304.  
  5305.                             List = (struct List *)Item -> Data;
  5306.  
  5307.                             for(Node = List -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
  5308.                             {
  5309.                                 if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
  5310.                                 {
  5311.                                     if(Examine(FileLock,FileInfo))
  5312.                                     {
  5313.                                         if(FileInfo -> fib_DirEntryType < 0)
  5314.                                         {
  5315.                                             if(AddFileTransferNode(Info,Node -> ln_Name,FileInfo -> fib_Size))
  5316.                                                 FilesFound++;
  5317.  
  5318.                                             if(Config -> TransferConfig -> TransferIcons)
  5319.                                             {
  5320.                                                 BPTR InfoLock;
  5321.  
  5322.                                                 strcpy(SharedBuffer,Node -> ln_Name);
  5323.  
  5324.                                                 strcat(SharedBuffer,".info");
  5325.  
  5326.                                                 if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  5327.                                                 {
  5328.                                                     if(Examine(InfoLock,FileInfo))
  5329.                                                     {
  5330.                                                         if(FileInfo -> fib_DirEntryType < 0)
  5331.                                                         {
  5332.                                                             if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  5333.                                                                 FilesFound++;
  5334.                                                         }
  5335.                                                     }
  5336.  
  5337.                                                     UnLock(InfoLock);
  5338.                                                 }
  5339.                                             }
  5340.  
  5341.                                             Remove(Node);
  5342.  
  5343.                                             FreeVecPooled(Node);
  5344.                                         }
  5345.                                     }
  5346.  
  5347.                                     UnLock(FileLock);
  5348.                                 }
  5349.                             }
  5350.  
  5351.                             ThisProcess -> pr_WindowPtr = OldPtr;
  5352.  
  5353.                             FreeDosObject(DOS_FIB,FileInfo);
  5354.                         }
  5355.  
  5356.                         DeleteMsgItem(Item);
  5357.  
  5358.                         Item = NULL;
  5359.  
  5360.                         if(FilesFound)
  5361.                         {
  5362.                             BlockWindows();
  5363.  
  5364.                             SortFileTransferInfo(Info);
  5365.  
  5366.                             switch(Type)
  5367.                             {
  5368.                                 case UPLOAD_BINARY:
  5369.  
  5370.                                     BinaryTransfer        = TRUE;
  5371.                                     FileTransferInfo    = Info;
  5372.  
  5373.                                     StartXprSendFromList(TRANSFER_BINARY,TRUE);
  5374.  
  5375.                                     break;
  5376.  
  5377.                                 case UPLOAD_TEXT:
  5378.  
  5379.                                     BinaryTransfer        = FALSE;
  5380.                                     FileTransferInfo    = Info;
  5381.  
  5382.                                     StartXprSendFromList(TRANSFER_TEXT,TRUE);
  5383.  
  5384.                                     break;
  5385.                             }
  5386.  
  5387.                             ReleaseWindows();
  5388.                         }
  5389.                         else
  5390.                             FreeFileTransferInfo(Info);
  5391.                     }
  5392.                 }
  5393.                 else
  5394.                 {
  5395.                     UBYTE Type = Item -> Size;
  5396.  
  5397.                     DeleteMsgItem(Item);
  5398.  
  5399.                     Item = NULL;
  5400.  
  5401.                     if(Type == UPLOAD_BINARY)
  5402.                     {
  5403.                         BinaryTransfer = TRUE;
  5404.  
  5405.                         if(!StartXprSend(TRANSFER_BINARY,TRUE))
  5406.                             SerWrite(ZModemCancel,20);
  5407.                     }
  5408.                     else
  5409.                     {
  5410.                         BinaryTransfer = FALSE;
  5411.  
  5412.                         if(!StartXprSend(TRANSFER_TEXT,TRUE))
  5413.                             SerWrite(ZModemCancel,20);
  5414.                     }
  5415.                 }
  5416.  
  5417.                 break;
  5418.  
  5419.                 // ARexx script execution finished.
  5420.  
  5421.             case DATAMSGTYPE_COMMANDDONE:
  5422.  
  5423.                 if(CantQuit > 0)
  5424.                     CantQuit--;
  5425.  
  5426.                 BumpWindow(Window);
  5427.  
  5428.                 ReleaseWindows();
  5429.  
  5430.                 ObtainSemaphore(&ARexxQueueSemaphore);
  5431.  
  5432.                 ARexxRunning = FALSE;
  5433.  
  5434.                 if(ARexxQueue . lh_Head -> ln_Succ)
  5435.                 {
  5436.                     struct Node *Node;
  5437.  
  5438.                     if(Node = RemHead(&ARexxQueue))
  5439.                     {
  5440.                         ReleaseSemaphore(&ARexxQueueSemaphore);
  5441.  
  5442.                         SendARexxCommand(Node -> ln_Name,FALSE);
  5443.  
  5444.                         FreeNode(Node);
  5445.                     }
  5446.                     else
  5447.                         ReleaseSemaphore(&ARexxQueueSemaphore);
  5448.                 }
  5449.                 else
  5450.                     ReleaseSemaphore(&ARexxQueueSemaphore);
  5451.  
  5452.                 break;
  5453.  
  5454.                 // Call a menu item
  5455.  
  5456.             case DATAMSGTYPE_MENU:
  5457.  
  5458.                 HandleMenuCode((ULONG)Item -> Size,(ULONG)Item -> Data);
  5459.  
  5460.                 break;
  5461.  
  5462.                 // Rendezvous with external process
  5463.  
  5464.             case DATAMSGTYPE_RENDEZVOUS:
  5465.  
  5466.                 if(ReadRequest && WriteRequest)
  5467.                 {
  5468.                         // Abort serial I/O processing
  5469.  
  5470.                     ClearSerial();
  5471.  
  5472.                     BlockWindows();
  5473.  
  5474.                         // Return the message, caution, we're not ready yet
  5475.  
  5476.                     Forbid();
  5477.  
  5478.                     DeleteMsgItem(Item);
  5479.  
  5480.                     Item = NULL;
  5481.  
  5482.                         // Prepare to wait...
  5483.  
  5484.                     ClrSignal(SIG_HANDSHAKE);
  5485.  
  5486.                     Wait(SIG_HANDSHAKE);
  5487.  
  5488.                         // Pick up the queue
  5489.  
  5490.                     RestartSerial(FALSE);
  5491.  
  5492.                     Permit();
  5493.  
  5494.                     ReleaseWindows();
  5495.                 }
  5496.  
  5497.                 break;
  5498.         }
  5499.  
  5500.         if(Item)
  5501.             DeleteMsgItem(Item);
  5502.  
  5503.         return(TRUE);
  5504.     }
  5505.     else
  5506.         return(FALSE);
  5507. }
  5508.  
  5509.     /* HandleOwnDevUnit():
  5510.      *
  5511.      *    Deal with the OwnDevUnit signal notification.
  5512.      */
  5513.  
  5514. BYTE
  5515. HandleOwnDevUnit()
  5516. {
  5517.     ObtainSemaphore(&OnlineSemaphore);
  5518.  
  5519.     if(!Online || !ReadPort)
  5520.     {
  5521.         ReleaseSemaphore(&OnlineSemaphore);
  5522.  
  5523.         if(Config -> SerialConfig -> SatisfyODURequests == ODU_RELEASE)
  5524.             HandleSerialRelease();
  5525.  
  5526.         if(Config -> SerialConfig -> SatisfyODURequests == ODU_WAIT)
  5527.         {
  5528.             APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  5529.             BYTE    Continue,SerialClosed;
  5530.  
  5531.             ThisProcess -> pr_WindowPtr = (APTR)Window;
  5532.  
  5533.                 /* This might happen if an ARexx user
  5534.                  * released the serial device and
  5535.                  * failed to reopen it.
  5536.                  */
  5537.  
  5538.             if(ReadPort)
  5539.                 SerialClosed = FALSE;
  5540.             else
  5541.                 SerialClosed = TRUE;
  5542.  
  5543.             BlockWindows();
  5544.  
  5545.                 /* Prevent catastrophes! */
  5546.  
  5547.             ObtainSemaphore(&OnlineSemaphore);
  5548.  
  5549.             if(Online && !SerialClosed)
  5550.             {
  5551.                 ReleaseSemaphore(&OnlineSemaphore);
  5552.  
  5553.                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  5554.                     Continue = FALSE;
  5555.                 else
  5556.                     Continue = TRUE;
  5557.             }
  5558.             else
  5559.             {
  5560.                 ReleaseSemaphore(&OnlineSemaphore);
  5561.  
  5562.                 Continue = TRUE;
  5563.             }
  5564.  
  5565.             if(Continue)
  5566.             {
  5567.                 if(!SerialClosed)
  5568.                 {
  5569.                     ClearSerial();
  5570.  
  5571.                     DeleteSerial();
  5572.  
  5573.                 }
  5574.             }
  5575.  
  5576.             ThisProcess -> pr_WindowPtr = OldPtr;
  5577.  
  5578.             ReleaseWindows();
  5579.  
  5580.                 // Start polling for the device to become
  5581.                 // available again
  5582.  
  5583.             PollODU = TRUE;
  5584.         }
  5585.     }
  5586.     else
  5587.         ReleaseSemaphore(&OnlineSemaphore);
  5588.  
  5589.     return(FALSE);
  5590. }
  5591.  
  5592.     /* FullHangup():
  5593.      *
  5594.      *    In a nutshell, do the full work required to hang up the line.
  5595.      */
  5596.  
  5597. VOID __regargs
  5598. FullHangup(BOOL ForceIt)
  5599. {
  5600.     BlockWindows();
  5601.  
  5602.     if(DialMsg)
  5603.     {
  5604.         DialMsg -> rm_Result1 = RC_WARN;
  5605.         DialMsg -> rm_Result2 = 0;
  5606.  
  5607.         ReplyMsg(DialMsg);
  5608.  
  5609.         DialMsg = NULL;
  5610.     }
  5611.  
  5612.     HangUp();
  5613.  
  5614.     ReleaseWindows();
  5615.  
  5616.     if(Config -> SerialConfig -> CheckCarrier && !ForceIt && !Config -> SerialConfig -> DirectConnection)
  5617.         HungUp = TRUE;
  5618.     else
  5619.     {
  5620.         ObtainSemaphore(&OnlineSemaphore);
  5621.  
  5622.         if(Online)
  5623.         {
  5624.                 /* Remember online state. */
  5625.  
  5626.             WasOnline = Online;
  5627.  
  5628.                 /* We are no longer online. */
  5629.  
  5630.             Online = FALSE;
  5631.         }
  5632.  
  5633.         ReleaseSemaphore(&OnlineSemaphore);
  5634.  
  5635.         HandleOnlineCleanup(TRUE);
  5636.     }
  5637. }
  5638.